diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11 | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11')
30 files changed, 7819 insertions, 0 deletions
diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11Renderer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11Renderer.cpp new file mode 100644 index 00000000..ea820c3d --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11Renderer.cpp @@ -0,0 +1,1467 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include "D3D11Renderer.h" + +#include <RendererDesc.h> + +#include <RendererProjection.h> + +#include <RendererVertexBufferDesc.h> +#include "D3D11RendererVertexBuffer.h" + +#include <RendererIndexBufferDesc.h> +#include "D3D11RendererIndexBuffer.h" + +#include <RendererInstanceBufferDesc.h> +#include "D3D11RendererInstanceBuffer.h" + +#include <RendererMeshDesc.h> +#include <RendererMeshContext.h> +#include "D3D11RendererMesh.h" + +#include <RendererMaterialDesc.h> +#include <RendererMaterialInstance.h> +#include "D3D11RendererMaterial.h" + +#include <RendererLightDesc.h> +#include <RendererDirectionalLightDesc.h> +#include "D3D11RendererDirectionalLight.h" +#include <RendererSpotLightDesc.h> +#include "D3D11RendererSpotLight.h" + +#include <RendererTextureDesc.h> +#include "D3D11RendererTexture2D.h" +#include "D3D11RendererTexture3D.h" + +#include <RendererTargetDesc.h> +#include "D3D11RendererTarget.h" + +#include "D3D11RendererResourceManager.h" +#include "D3D11RendererVariableManager.h" +#include "D3D11RendererMemoryMacros.h" +#include "D3D11RendererUtils.h" + +#include <PsUtilities.h> +#include <SamplePlatform.h> +#include <deque> + +using namespace SampleRenderer; +using std::tr1::get; + +void SampleRenderer::convertToD3D11(PxVec3& dxcolor, const RendererColor& color) +{ + static const float inv255 = 1.0f / 255.0f; + dxcolor = PxVec3(color.r * inv255, color.g * inv255, color.b * inv255); +} + +void SampleRenderer::convertToD3D11(PxVec4& dxcolor, const RendererColor& color) +{ + static const float inv255 = 1.0f / 255.0f; + dxcolor = PxVec4(color.r * inv255, color.g * inv255, color.b * inv255, color.a * inv255); +} + +void SampleRenderer::convertToD3D11(PxMat44& dxmat, const physx::PxMat44 &mat) +{ + dxmat = mat.getTranspose(); +} + +void SampleRenderer::convertToD3D11(PxMat44& dxmat, const RendererProjection& mat) +{ + convertToD3D11(dxmat, mat.getPxMat44()); +} + +/**************************************** +* D3D11Renderer::D3D11ShaderEnvironment * +****************************************/ + +D3D11Renderer::D3D11ShaderEnvironment::D3D11ShaderEnvironment() +{ + memset(this, 0, sizeof(*this)); + vfs = 1.; +} + +#define SHADER_VAR_NAME(_name) PX_STRINGIZE(PX_CONCAT(g_, _name)) + +void D3D11Renderer::D3D11ShaderEnvironment::bindFrame() const +{ + constantManager->setSharedVariable("cbFrame", SHADER_VAR_NAME(viewMatrix), &viewMatrix); + constantManager->setSharedVariable("cbFrame", SHADER_VAR_NAME(projMatrix), &projMatrix); + constantManager->setSharedVariable("cbFrame", SHADER_VAR_NAME(eyePosition), &eyePosition.x); + constantManager->setSharedVariable("cbFrame", SHADER_VAR_NAME(eyeDirection), &eyeDirection.x); + constantManager->setSharedVariable("cbFrameInv", SHADER_VAR_NAME(invViewProjMatrix), &invViewProjMatrix); +} + +void D3D11Renderer::D3D11ShaderEnvironment::bindLight(PxU32 lightIndex) const +{ + RENDERER_ASSERT(lightIndex < RENDERER_MAX_LIGHTS, "Invalid light index"); + if (lightIndex < RENDERER_MAX_LIGHTS) + { + if (numLights < ((int)lightIndex + 1)) numLights = lightIndex + 1; + const char* lightName = RENDERER_ENABLE_SINGLE_PASS_LIGHTING ? "cbLights" : "cbLight"; + constantManager->setSharedVariable(lightName, SHADER_VAR_NAME(lightColor), &lightColor[lightIndex].x, sizeof(PxVec3), lightIndex*sizeof(PxVec3)); + constantManager->setSharedVariable(lightName, SHADER_VAR_NAME(lightDirection), &lightDirection[lightIndex].x, sizeof(PxVec3), lightIndex*sizeof(PxVec3)); + constantManager->setSharedVariable(lightName, SHADER_VAR_NAME(lightPosition), &lightPosition[lightIndex].x, sizeof(PxVec3), lightIndex*sizeof(PxVec3)); + constantManager->setSharedVariable(lightName, SHADER_VAR_NAME(lightIntensity), &lightIntensity[lightIndex], sizeof(float), lightIndex*sizeof(float)); + constantManager->setSharedVariable(lightName, SHADER_VAR_NAME(lightInnerRadius), &lightInnerRadius[lightIndex], sizeof(float), lightIndex*sizeof(float)); + constantManager->setSharedVariable(lightName, SHADER_VAR_NAME(lightOuterRadius), &lightOuterRadius[lightIndex], sizeof(float), lightIndex*sizeof(float)); + constantManager->setSharedVariable(lightName, SHADER_VAR_NAME(lightInnerCone), &lightInnerCone[lightIndex], sizeof(float), lightIndex*sizeof(float)); + constantManager->setSharedVariable(lightName, SHADER_VAR_NAME(lightOuterCone), &lightOuterCone[lightIndex], sizeof(float), lightIndex*sizeof(float)); +#if RENDERER_ENABLE_SINGLE_PASS_LIGHTING + constantManager->setSharedVariable(lightName, SHADER_VAR_NAME(lightType), &lightType[lightIndex], sizeof(int), lightIndex*sizeof(int)); + constantManager->setSharedVariable(lightName, SHADER_VAR_NAME(numLights), &numLights, sizeof(int)); +#endif + +#if RENDERER_ENABLE_SHADOWS + if (lightShadowMap) + { + // The actual shadow map texture will be bound as a variable of the material + constantManager->setSharedVariable("cbLightShadow", SHADER_VAR_NAME(lightShadowMatrix), &lightShadowMatrix); + } +#endif + } +} + +void D3D11Renderer::D3D11ShaderEnvironment::bindModel() const +{ + constantManager->setSharedVariable("cbMesh", SHADER_VAR_NAME(modelMatrix), &modelMatrix); + constantManager->setSharedVariable("cbMesh", SHADER_VAR_NAME(modelViewMatrix), &modelViewMatrix); + constantManager->setSharedVariable("cbMesh", SHADER_VAR_NAME(modelViewProjMatrix), &modelViewProjMatrix); +} + +void D3D11Renderer::D3D11ShaderEnvironment::bindBones() const +{ + if (numBones > 0) + { + constantManager->setSharedVariable("cbBones", SHADER_VAR_NAME(boneMatrices), &boneMatrices[0], numBones * sizeof(PxMat44)); + } +} + +void D3D11Renderer::D3D11ShaderEnvironment::bindFogState() const +{ + constantManager->setSharedVariable("cbFog", SHADER_VAR_NAME(fogColorAndDistance), &fogColorAndDistance.x); +} + +void D3D11Renderer::D3D11ShaderEnvironment::bindAmbientState() const +{ + constantManager->setSharedVariable("cbAmbient", SHADER_VAR_NAME(ambientColor), &ambientColor.x); +} + +void D3D11Renderer::D3D11ShaderEnvironment::bindVFaceScale() const +{ +#if defined(RENDERER_ENABLE_VFACE_SCALE) + constantManager->setSharedVariable("cbScale", SHADER_VAR_NAME(vfaceScale), &vfs); +#endif +} + +void D3D11Renderer::D3D11ShaderEnvironment::reset() +{ + numLights = 0; +} + +#undef SHADER_VAR_NAME + +/*************** +* D3D11Renderer * +***************/ + +static std::deque<ID3D11BlendState*> gBlendState; +static std::deque<ID3D11DepthStencilState*> gDepthStencilState; +static std::deque<ID3D11RasterizerState*> gRasterizerState; +static std::deque<D3D11_VIEWPORT> gViewport; +static std::deque<PxVec4> gBlendFactor; +static std::deque<UINT> gBlendMask; +static std::deque<UINT> gDepthStencilMask; + +D3D11Renderer::D3D11Renderer(const RendererDesc& desc, const char* assetDir) : + Renderer(DRIVER_DIRECT3D11, desc.errorCallback, assetDir), + m_displayWidth(0), + m_displayHeight(0), + m_displayBuffer(0), + m_vsync(desc.vsync), + m_multipassDepthBias(desc.multipassDepthBias ? -1 : 0), + m_d3d(NULL), + m_d3dSwapChain(NULL), + m_d3dDevice(NULL), + m_d3dDeviceContext(NULL), + m_d3dDeviceFeatureLevel(D3D_FEATURE_LEVEL_11_0), + m_d3dDepthStencilBuffer(NULL), + m_d3dDepthStencilView(NULL), + m_d3dRenderTargetBuffer(NULL), + m_d3dRenderTargetView(NULL), + m_currentTextMesh(0), + m_linesMesh(NULL), + m_linesVertices(NULL), + m_d3dx(NULL), + m_constantManager(NULL), + m_resourceManager(NULL) +{ + for (PxU32 i = 0; i < NUM_BLEND_STATES; ++i) + m_d3dBlendStates[i] = NULL; + for (PxU32 i = 0; i < NUM_DEPTH_STENCIL_STATES; ++i) + m_d3dDepthStencilStates[i] = NULL; + + m_useShadersForTextRendering = true; + m_pixelCenterOffset = 0.f; + m_viewMatrix = physx::PxMat44(PxIdentity); + + SampleFramework::SamplePlatform* m_platform = SampleFramework::SamplePlatform::platform(); + m_d3d = static_cast<IDXGIFactory*>(m_platform->initializeD3D11()); + RENDERER_ASSERT(m_d3d, "Could not create Direct3D11 Interface."); + if (m_d3d) + { + // Setup swap chain configuration + memset(&m_swapChainDesc, 0, sizeof(m_swapChainDesc)); + m_swapChainDesc.BufferCount = 1; + m_swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + m_swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + m_swapChainDesc.BufferDesc.Height = m_displayHeight; + m_swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; + m_swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; + m_swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + m_swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + m_swapChainDesc.BufferDesc.Width = m_displayWidth; + m_swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH ; + m_swapChainDesc.SampleDesc.Count = 1; + m_swapChainDesc.SampleDesc.Quality = 0; + m_swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + m_swapChainDesc.Windowed = 1; + + HRESULT hr = m_platform->initializeD3D11Display( + &m_swapChainDesc, + m_deviceName, + m_displayWidth, + m_displayHeight, + &m_d3dDevice, + &m_d3dDeviceContext, + &m_d3dSwapChain); + RENDERER_ASSERT(SUCCEEDED(hr), "Failed to create Direct3D11 Device."); + if (SUCCEEDED(hr)) + { + m_d3dDeviceFeatureLevel = m_d3dDevice->GetFeatureLevel(); + setEnableTessellation(true); + checkResize(false); + } + } + + D3D11RendererVariableManager::StringSet cbNames; + cbNames.insert("cbAllData"); + cbNames.insert("cbMesh"); + cbNames.insert("cbFrame"); + cbNames.insert("cbFrameInv"); + cbNames.insert("cbBones"); + cbNames.insert("cbFog"); + cbNames.insert("cbAmbient"); + cbNames.insert("cbLight"); + cbNames.insert("cbLights"); + cbNames.insert("cbLightShadow"); + cbNames.insert("cbScale"); + cbNames.insert("cbTessellation"); + + m_d3dx = new D3DX11(); + m_constantManager = new D3D11RendererVariableManager(*this, cbNames /*, D3D11RendererVariableManager::BIND_MAP*/); + m_resourceManager = new D3D11RendererResourceManager( ); + m_environment.constantManager = m_constantManager; +} + +D3D11Renderer::~D3D11Renderer(void) +{ + releaseAllMaterials(); + + if (m_d3dDeviceContext) + { + m_d3dDeviceContext->ClearState(); + m_d3dDeviceContext->Flush(); + } + + dxSafeRelease(m_displayBuffer); + + dxSafeRelease(m_d3d); + dxSafeRelease(m_d3dSwapChain); + dxSafeRelease(m_d3dDevice); + dxSafeRelease(m_d3dDeviceContext); + + dxSafeRelease(m_d3dDepthStencilBuffer); + dxSafeRelease(m_d3dDepthStencilView); + dxSafeRelease(m_d3dRenderTargetBuffer); + dxSafeRelease(m_d3dRenderTargetView); + + for (PxU32 i = 0; i < NUM_BLEND_STATES; ++i) + dxSafeRelease(m_d3dBlendStates[i]); + for (PxU32 i = 0; i < NUM_DEPTH_STENCIL_STATES; ++i) + dxSafeRelease(m_d3dDepthStencilStates[i]); + + dxSafeReleaseAll(gRasterizerState); + dxSafeReleaseAll(gBlendState); + dxSafeReleaseAll(gDepthStencilState); + + deleteAll(m_textMeshes); + deleteAll(m_textVertices); + deleteAll(m_textIndices); + + delete m_linesMesh; + delete m_linesVertices; + + delete m_constantManager; + delete m_resourceManager; + delete m_d3dx; +} + +bool D3D11Renderer::checkResize(bool resetDevice) +{ + bool isDeviceReset = false; +#if defined(RENDERER_WINDOWS) + if (SampleFramework::SamplePlatform::platform()->getWindowHandle() && m_d3dDevice) + { + PxU32 width = 0; + PxU32 height = 0; + SampleFramework::SamplePlatform::platform()->getWindowSize(width, height); + if (width && height && (width != m_displayWidth || height != m_displayHeight) || resetDevice) + { + m_displayWidth = width; + m_displayHeight = height; + m_d3dDeviceContext->ClearState(); + m_d3dDeviceContext->OMSetRenderTargets(0, NULL, NULL); + + dxSafeRelease(m_d3dRenderTargetView); + dxSafeRelease(m_d3dRenderTargetBuffer); + dxSafeRelease(m_d3dDepthStencilView); + dxSafeRelease(m_d3dDepthStencilBuffer); + + HRESULT hr = S_OK; + DXGI_SWAP_CHAIN_DESC desc; + m_d3dSwapChain->GetDesc(&desc); + if(desc.BufferDesc.Width != width || desc.BufferDesc.Height != height) + hr = m_d3dSwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0); + RENDERER_ASSERT(SUCCEEDED(hr), "Failed to resize swap chain buffers."); + + D3D11_TEXTURE2D_DESC depthDesc; + depthDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + if (SUCCEEDED(hr)) + { + depthDesc.Width = m_displayWidth; + depthDesc.Height = m_displayHeight; + depthDesc.MipLevels = 1; + depthDesc.ArraySize = 1; + depthDesc.SampleDesc.Count = m_swapChainDesc.SampleDesc.Count; + depthDesc.SampleDesc.Quality = m_swapChainDesc.SampleDesc.Quality; + depthDesc.Usage = D3D11_USAGE_DEFAULT; + depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + depthDesc.CPUAccessFlags = 0; + depthDesc.MiscFlags = 0; + + hr = m_d3dDevice->CreateTexture2D(&depthDesc, NULL, &m_d3dDepthStencilBuffer); + RENDERER_ASSERT(SUCCEEDED(hr), "Failed to create depth stencil buffer."); + } + + if (SUCCEEDED(hr)) + { + hr = m_d3dSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&m_d3dRenderTargetBuffer); + RENDERER_ASSERT(SUCCEEDED(hr), "Failed to acquire swap chain buffer."); + } + + if (SUCCEEDED(hr) && m_d3dRenderTargetBuffer) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + //rtvDesc.Texture2D.MipSlice = 0; + hr = m_d3dDevice->CreateRenderTargetView(m_d3dRenderTargetBuffer, &rtvDesc, &m_d3dRenderTargetView); + RENDERER_ASSERT(SUCCEEDED(hr), "Failed to create render target view."); + } + + if (SUCCEEDED(hr)) + { + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; + dsvDesc.Format = depthDesc.Format; + dsvDesc.Flags = 0; + //dsvDesc.Texture2D.MipSlice = 0; + hr = m_d3dDevice->CreateDepthStencilView(m_d3dDepthStencilBuffer, &dsvDesc, &m_d3dDepthStencilView); + RENDERER_ASSERT(SUCCEEDED(hr), "Failed to create depth stencil view."); + } + + m_d3dDeviceContext->OMSetRenderTargets(1, &m_d3dRenderTargetView, m_d3dDepthStencilView); + + if (resetDevice) + { + onDeviceReset(); + isDeviceReset = true; + } + + PxU32 NUM_VIEWPORTS = 1; + D3D11_VIEWPORT viewport[1]; + ZeroMemory(viewport, sizeof(D3D11_VIEWPORT)*NUM_VIEWPORTS); + m_d3dDeviceContext->RSGetViewports(&NUM_VIEWPORTS, viewport); + viewport[0].Width = (FLOAT)m_displayWidth; + viewport[0].Height = (FLOAT)m_displayHeight; + viewport[0].MinDepth = 0.0f; + viewport[0].MaxDepth = 1.0f; + m_d3dDeviceContext->RSSetViewports(1, viewport); + } + } + +#endif + return isDeviceReset; +} + +void D3D11Renderer::onDeviceLost(void) +{ + notifyResourcesLostDevice(); +} + +void D3D11Renderer::onDeviceReset(void) +{ + notifyResourcesResetDevice(); +} + +// clears the offscreen buffers. +void D3D11Renderer::clearBuffers(void) +{ + if (m_d3dDeviceContext && m_d3dRenderTargetView) + { + PxVec4 clearColor; + convertToD3D11(clearColor, getClearColor()); + m_d3dDeviceContext->ClearRenderTargetView(m_d3dRenderTargetView, &clearColor.x); + } + if (m_d3dDeviceContext && m_d3dDepthStencilView) + { + m_d3dDeviceContext->ClearDepthStencilView(m_d3dDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0, 0); + } +} + +// presents the current color buffer to the screen. +// returns true on device reset and if buffers need to be rewritten. +bool D3D11Renderer::swapBuffers(void) +{ + PX_PROFILE_ZONE("SwapBuffers", 0); + bool isDeviceReset = false; + if (m_d3dDevice) + { + HRESULT result = SampleFramework::SamplePlatform::platform()->D3D11Present(m_vsync); + if ( DXGI_STATUS_OCCLUDED == result ) + { + // This is fine, though we should set a flag to use a "test" D3D11Present + // for the next frame until the window is no longer occluded + } + else if (SUCCEEDED(result) || DXGI_ERROR_DEVICE_RESET == result) + { + isDeviceReset = checkResize(DXGI_ERROR_DEVICE_RESET == result); + } + } + return isDeviceReset; +} + +void D3D11Renderer::getWindowSize(PxU32& width, PxU32& height) const +{ + RENDERER_ASSERT(m_displayHeight * m_displayWidth > 0, "variables not initialized properly"); + width = m_displayWidth; + height = m_displayHeight; +} + +RendererVertexBuffer* D3D11Renderer::createVertexBuffer(const RendererVertexBufferDesc& desc) +{ + D3D11RendererVertexBuffer* vb = 0; + if (m_d3dDevice) + { + RENDERER_ASSERT(desc.isValid(), "Invalid Vertex Buffer Descriptor."); + if (desc.isValid()) + { + vb = new D3D11RendererVertexBuffer(*m_d3dDevice, *m_d3dDeviceContext, desc); + } + } + if (vb) + { + addResource(*vb); + } + return vb; +} + +RendererIndexBuffer* D3D11Renderer::createIndexBuffer(const RendererIndexBufferDesc& desc) +{ + D3D11RendererIndexBuffer* ib = 0; + if (m_d3dDevice) + { + RENDERER_ASSERT(desc.isValid(), "Invalid Index Buffer Descriptor."); + if (desc.isValid()) + { + ib = new D3D11RendererIndexBuffer(*m_d3dDevice, *m_d3dDeviceContext, desc); + } + } + if (ib) + { + addResource(*ib); + } + return ib; +} + +RendererInstanceBuffer* D3D11Renderer::createInstanceBuffer(const RendererInstanceBufferDesc& desc) +{ + D3D11RendererInstanceBuffer* ib = 0; + if (m_d3dDevice) + { + RENDERER_ASSERT(desc.isValid(), "Invalid Instance Buffer Descriptor."); + if (desc.isValid()) + { + ib = new D3D11RendererInstanceBuffer(*m_d3dDevice, *m_d3dDeviceContext, desc); + } + } + if (ib) + { + addResource(*ib); + } + return ib; +} + +RendererTexture2D* D3D11Renderer::createTexture2D(const RendererTexture2DDesc& desc) +{ + D3D11RendererTexture2D* texture = 0; + if (m_d3dDevice) + { + RENDERER_ASSERT(desc.isValid(), "Invalid Texture 2D Descriptor."); + if (desc.isValid()) + { + texture = new D3D11RendererTexture2D(*m_d3dDevice, *m_d3dDeviceContext, desc); + } + } + if (texture) + { + addResource(*texture); + } + return texture; +} + +RendererTexture3D* D3D11Renderer::createTexture3D(const RendererTexture3DDesc& desc) +{ + D3D11RendererTexture3D* texture = 0; + if (m_d3dDevice) + { + RENDERER_ASSERT(desc.isValid(), "Invalid Texture 3D Descriptor."); + if (desc.isValid()) + { + texture = new D3D11RendererTexture3D(*m_d3dDevice, *m_d3dDeviceContext, desc); + } + } + if (texture) + { + addResource(*texture); + } + return texture; +} + +RendererTarget* D3D11Renderer::createTarget(const RendererTargetDesc& desc) +{ + RendererTarget* target = 0; +#if defined(RENDERER_ENABLE_DIRECT3D11_TARGET) + D3D11RendererTarget* d3dTarget = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Target Descriptor."); + if (desc.isValid()) + { + d3dTarget = new D3D11RendererTarget(*m_d3dDevice, *m_d3dDeviceContext, desc); + } + if (d3dTarget) + { + addResource(*d3dTarget); + } + target = d3dTarget; +#endif + return target; +} + +RendererMaterial* D3D11Renderer::createMaterial(const RendererMaterialDesc& desc) +{ + RendererMaterial* mat = hasMaterialAlready(desc); + RENDERER_ASSERT(desc.isValid(), "Invalid Material Descriptor."); + if (!mat && desc.isValid()) + { + mat = new D3D11RendererMaterial(*this, desc); + + registerMaterial(desc, mat); + } + return mat; +} + +RendererMesh* D3D11Renderer::createMesh(const RendererMeshDesc& desc) +{ + D3D11RendererMesh* mesh = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Mesh Descriptor."); + if (desc.isValid()) + { + mesh = new D3D11RendererMesh(*this, desc); + } + return mesh; +} + +RendererLight* D3D11Renderer::createLight(const RendererLightDesc& desc) +{ + RendererLight* light = 0; + if (m_d3dDevice) + { + RENDERER_ASSERT(desc.isValid(), "Invalid Light Descriptor."); + if (desc.isValid()) + { + switch (desc.type) + { + case RendererLight::TYPE_DIRECTIONAL: + light = new D3D11RendererDirectionalLight(*this, *(RendererDirectionalLightDesc*)&desc); + break; + case RendererLight::TYPE_SPOT: + light = new D3D11RendererSpotLight(*this, *(RendererSpotLightDesc*)&desc); + break; + default: + RENDERER_ASSERT(0, "Not implemented!"); + } + } + } + return light; +} + +void D3D11Renderer::setVsync(bool on) +{ + m_vsync = on; +} + +bool D3D11Renderer::beginRender(void) +{ + setBlendState(); + + setRasterizerState(); + + setTessellationState(); + + m_environment.reset(); + m_currentTextMesh = 0; + return true; +} + +void D3D11Renderer::endRender(void) +{ + +} + +void D3D11Renderer::bindViewProj(const physx::PxMat44& eye, const RendererProjection& proj) +{ + m_viewMatrix = eye.inverseRT(); + + convertToD3D11(m_environment.viewMatrix, m_viewMatrix); + convertToD3D11(m_environment.invViewProjMatrix, eye); + convertToD3D11(m_environment.projMatrix, proj); + + m_environment.eyePosition = eye.getPosition(); + m_environment.eyeDirection = -eye.getBasis(2); + + m_environment.bindFrame(); +} + +void D3D11Renderer::bindFogState(const RendererColor& fogColor, float fogDistance) +{ + const float inv255 = 1.0f / 255.0f; + + m_environment.fogColorAndDistance.x = fogColor.r * inv255; + m_environment.fogColorAndDistance.y = fogColor.g * inv255; + m_environment.fogColorAndDistance.z = fogColor.b * inv255; + m_environment.fogColorAndDistance.w = fogDistance; + m_environment.bindFogState(); +} + +void D3D11Renderer::bindAmbientState(const RendererColor& ambientColor) +{ + convertToD3D11(m_environment.ambientColor, ambientColor); + m_environment.bindAmbientState(); +} + +void D3D11Renderer::bindDeferredState(void) +{ + RENDERER_ASSERT(0, "Not implemented!"); +} + +void D3D11Renderer::bindMeshContext(const RendererMeshContext& context) +{ + physx::PxMat44 model; + physx::PxMat44 modelView; + if(context.transform) model = *context.transform; + else model = PxMat44(PxIdentity); + modelView = m_viewMatrix * model; + + convertToD3D11(m_environment.modelMatrix, model); + convertToD3D11(m_environment.modelViewMatrix, modelView); + m_environment.bindModel(); + + + // it appears that D3D winding is backwards, so reverse them... + D3D11_CULL_MODE cullMode = D3D11_CULL_BACK; + switch (context.cullMode) + { + case RendererMeshContext::CLOCKWISE: + cullMode = context.negativeScale ? D3D11_CULL_BACK : D3D11_CULL_FRONT; + break; + case RendererMeshContext::COUNTER_CLOCKWISE: + cullMode = context.negativeScale ? D3D11_CULL_FRONT : D3D11_CULL_BACK; + break; + case RendererMeshContext::NONE: + cullMode = D3D11_CULL_NONE; + break; + default: + RENDERER_ASSERT(0, "Invalid Cull Mode"); + } + if (!blendingCull() && NULL != context.material && context.material->getBlending()) + cullMode = D3D11_CULL_NONE; + + D3D11_FILL_MODE fillMode = D3D11_FILL_SOLID; + switch (context.fillMode) + { + case RendererMeshContext::SOLID: + fillMode = D3D11_FILL_SOLID; + break; + case RendererMeshContext::LINE: + fillMode = D3D11_FILL_WIREFRAME; + break; + case RendererMeshContext::POINT: + fillMode = D3D11_FILL_SOLID; + break; + default: + RENDERER_ASSERT(0, "Invalid Fill Mode"); + } + if (wireframeEnabled()) + { + fillMode = D3D11_FILL_WIREFRAME; + } + + setRasterizerState(fillMode, cullMode, get<2>(m_boundRasterizerStateKey)); + + RENDERER_ASSERT(context.numBones <= RENDERER_MAX_BONES, "Too many bones."); + if (context.boneMatrices && context.numBones > 0 && context.numBones <= RENDERER_MAX_BONES) + { + for (PxU32 i = 0; i < context.numBones; ++i) + { + convertToD3D11(m_environment.boneMatrices[i], context.boneMatrices[i]); + } + m_environment.numBones = context.numBones; + m_environment.bindBones(); + } +} + +void D3D11Renderer::setRasterizerState(D3D11_FILL_MODE fillMode, D3D11_CULL_MODE cullMode, PxI32 depthBias) +{ + + D3DTraits<ID3D11RasterizerState>::key_type rasterizerStateKey(fillMode, cullMode, depthBias); + + ID3D11RasterizerState* pRasterizerState = + getResourceManager()->hasResource<ID3D11RasterizerState>(rasterizerStateKey); + if (NULL == pRasterizerState) + { + RENDERER_ASSERT(m_d3dDevice, "Invalid D3D11 device."); + D3D11_RASTERIZER_DESC rasterizerDesc = + { + fillMode, // D3D11_FILL_MODE FillMode; + cullMode, // D3D11_CULL_MODE CullMode; + TRUE, // BOOL FrontCounterClockwise; + 0, // INT DepthBias; + .05f * depthBias, // FLOAT DepthBiasClamp; + .05f * depthBias, // FLOAT SlopeScaledDepthBias; + FALSE, // BOOL DepthClipEnable; + FALSE, // BOOL ScissorEnable; + (fillMode == D3D11_FILL_WIREFRAME) ? FALSE : TRUE, // BOOL MultisampleEnable; + FALSE, // BOOL AntialiasedLineEnable; + }; + if(getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) + { + rasterizerDesc.DepthClipEnable = TRUE; + } + HRESULT result = m_d3dDevice->CreateRasterizerState(&rasterizerDesc, &pRasterizerState); + RENDERER_ASSERT(SUCCEEDED(result) && pRasterizerState, "Error creating D3D11 rasterizer state."); + if (SUCCEEDED(result)) + { + getResourceManager()->registerResource<ID3D11RasterizerState>(rasterizerStateKey, pRasterizerState); + } + } + RENDERER_ASSERT(pRasterizerState, "Invalid D3D11RasterizerState"); + if (pRasterizerState && m_d3dDeviceContext) + { + m_d3dDeviceContext->RSSetState(pRasterizerState); + if (get<1>(m_boundRasterizerStateKey) != get<1>(rasterizerStateKey)) + { + m_environment.vfs = (get<1>(rasterizerStateKey) == D3D11_CULL_BACK) ? 1.f : -1.f; + m_environment.bindVFaceScale(); + } + m_boundRasterizerStateKey = rasterizerStateKey; + } +} + + +void SampleRenderer::D3D11Renderer::setDepthStencilState(DepthStencilState state) +{ + if (!m_d3dDeviceContext || state >= NUM_DEPTH_STENCIL_STATES) + { + return; + } + + // The standard depth-stencil state + D3D11_DEPTH_STENCIL_DESC depthStencilDesc = + { + TRUE, // BOOL DepthEnable; + D3D11_DEPTH_WRITE_MASK_ALL, // D3D11_DEPTH_WRITE_MASK DepthWriteMask; + D3D11_COMPARISON_LESS, // D3D11_COMPARISON_FUNC DepthFunc; + TRUE, // BOOL StencilEnable; + 0xFF, // UINT8 StencilReadMask; + 0xFF, // UINT8 StencilWriteMask; + { + // D3D11_DEPTH_STENCILOP_DESC FrontFace; + D3D11_STENCIL_OP_KEEP, // D3D11_STENCIL_OP StencilFailOp; + D3D11_STENCIL_OP_INCR, // D3D11_STENCIL_OP StencilDepthFailOp; + D3D11_STENCIL_OP_KEEP, // D3D11_STENCIL_OP StencilPassOp; + D3D11_COMPARISON_ALWAYS, // D3D11_COMPARISON_FUNC StencilFunc; + }, + { + // D3D11_DEPTH_STENCILOP_DESC BackFace; + D3D11_STENCIL_OP_KEEP, // D3D11_STENCIL_OP StencilFailOp; + D3D11_STENCIL_OP_INCR, // D3D11_STENCIL_OP StencilDepthFailOp; + D3D11_STENCIL_OP_KEEP, // D3D11_STENCIL_OP StencilPassOp; + D3D11_COMPARISON_ALWAYS, // D3D11_COMPARISON_FUNC StencilFunc; + }, + }; + + if (!m_d3dDepthStencilStates[DEPTHSTENCIL_DEFAULT]) + { + m_d3dDevice->CreateDepthStencilState(&depthStencilDesc, &m_d3dDepthStencilStates[DEPTHSTENCIL_DEFAULT]); + RENDERER_ASSERT(m_d3dDepthStencilStates[DEPTHSTENCIL_DEFAULT], "Error creating D3D depth stencil state"); + } + if (!m_d3dDepthStencilStates[DEPTHSTENCIL_TRANSPARENT]) + { + depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; + depthStencilDesc.StencilWriteMask = 0x00; + m_d3dDevice->CreateDepthStencilState(&depthStencilDesc, &m_d3dDepthStencilStates[DEPTHSTENCIL_TRANSPARENT]); + RENDERER_ASSERT(m_d3dDepthStencilStates[DEPTHSTENCIL_TRANSPARENT], "Error creating D3D depth stencil state"); + } + if (!m_d3dDepthStencilStates[DEPTHSTENCIL_DISABLED]) + { + depthStencilDesc.DepthEnable = FALSE; + depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + depthStencilDesc.DepthFunc = D3D11_COMPARISON_NEVER; + depthStencilDesc.StencilEnable = FALSE; + depthStencilDesc.StencilReadMask = 0x00; + depthStencilDesc.StencilWriteMask = 0x00; + m_d3dDevice->CreateDepthStencilState(&depthStencilDesc, &m_d3dDepthStencilStates[DEPTHSTENCIL_DISABLED]); + RENDERER_ASSERT(m_d3dDepthStencilStates[DEPTHSTENCIL_DISABLED], "Error creating D3D depth stencil state"); + } + + m_d3dDeviceContext->OMSetDepthStencilState(m_d3dDepthStencilStates[state], 1); +} + +void SampleRenderer::D3D11Renderer::setBlendState(BlendState state) +{ + if (!m_d3dDeviceContext || state >= NUM_BLEND_STATES) + { + return; + } + + // BLEND_DEFAULT is purposefully NULL + if (!m_d3dBlendStates[BLEND_MULTIPASS] && m_d3dDevice) + { + D3D11_BLEND_DESC blendDesc; + memset(&blendDesc, 0, sizeof(blendDesc)); + if(getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) + { + blendDesc.AlphaToCoverageEnable = FALSE; + blendDesc.IndependentBlendEnable = FALSE; + } + else + { + blendDesc.AlphaToCoverageEnable = TRUE; + blendDesc.IndependentBlendEnable = TRUE; + } + blendDesc.RenderTarget[0].BlendEnable = TRUE; + blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + m_d3dDevice->CreateBlendState(&blendDesc, &m_d3dBlendStates[BLEND_MULTIPASS]); + RENDERER_ASSERT(m_d3dBlendStates[BLEND_MULTIPASS], "Error creating D3D blend state"); + } + if (!m_d3dBlendStates[BLEND_TRANSPARENT_ALPHA_COVERAGE] && m_d3dDevice) + { + D3D11_BLEND_DESC blendDesc; + memset(&blendDesc, 0, sizeof(blendDesc)); + if(getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) + { + blendDesc.AlphaToCoverageEnable = FALSE; + blendDesc.IndependentBlendEnable = FALSE; + } + else + { + blendDesc.AlphaToCoverageEnable = TRUE; + blendDesc.IndependentBlendEnable = TRUE; + } + blendDesc.RenderTarget[0].BlendEnable = TRUE; + blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + m_d3dDevice->CreateBlendState(&blendDesc, &m_d3dBlendStates[BLEND_TRANSPARENT_ALPHA_COVERAGE]); + RENDERER_ASSERT(m_d3dBlendStates[BLEND_TRANSPARENT_ALPHA_COVERAGE], "Error creating D3D blend state"); + } + if (!m_d3dBlendStates[BLEND_TRANSPARENT] && m_d3dDevice) + { + D3D11_BLEND_DESC blendDesc; + memset(&blendDesc, 0, sizeof(blendDesc)); + blendDesc.AlphaToCoverageEnable = FALSE; + if(getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) + { + blendDesc.IndependentBlendEnable = FALSE; + } + else + { + blendDesc.IndependentBlendEnable = TRUE; + } + blendDesc.RenderTarget[0].BlendEnable = TRUE; + blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + m_d3dDevice->CreateBlendState(&blendDesc, &m_d3dBlendStates[BLEND_TRANSPARENT]); + RENDERER_ASSERT(m_d3dBlendStates[BLEND_TRANSPARENT], "Error creating D3D blend state"); + } + + const FLOAT BlendFactor[4] = {0, 0, 0, 0}; + m_d3dDeviceContext->OMSetBlendState(m_d3dBlendStates[state], BlendFactor, 0xffffffff); +} + +void SampleRenderer::D3D11Renderer::setTessellationState() +{ + getVariableManager()->setSharedVariable("cbTessellation", "g_tessFactor", &getTessellationParams().tessFactor); + getVariableManager()->setSharedVariable("cbTessellation", "g_tessMinMaxDistance", &getTessellationParams().tessMinMaxDistance); + getVariableManager()->setSharedVariable("cbTessellation", "g_tessHeightScaleAndBias", &getTessellationParams().tessHeightScaleAndBias); + getVariableManager()->setSharedVariable("cbTessellation", "g_tessUVScale", &getTessellationParams().tessUVScale); +} + +bool D3D11Renderer::tessellationEnabled() const +{ + return getEnableTessellation(); +} + +bool D3D11Renderer::isTessellationSupported(void) const +{ + return m_d3dDeviceFeatureLevel >= D3D_FEATURE_LEVEL_11_0; +} + +bool D3D11Renderer::multisamplingEnabled() const +{ + return m_swapChainDesc.SampleDesc.Count > 1 && m_swapChainDesc.SampleDesc.Quality > 0; +} + +void D3D11Renderer::beginMultiPass(void) +{ + setBlendState(BLEND_MULTIPASS); + setDepthStencilState(DEPTHSTENCIL_TRANSPARENT); + setRasterizerState(get<0>(m_boundRasterizerStateKey), get<1>(m_boundRasterizerStateKey), m_multipassDepthBias); +} + +void D3D11Renderer::endMultiPass(void) +{ + setBlendState(BLEND_DEFAULT); + setDepthStencilState(DEPTHSTENCIL_DEFAULT); + setRasterizerState(get<0>(m_boundRasterizerStateKey), get<1>(m_boundRasterizerStateKey), 0); +} + +void D3D11Renderer::beginTransparentMultiPass(void) +{ + setEnableBlendingOverride(true); + setBlendState(BLEND_TRANSPARENT_ALPHA_COVERAGE); + setDepthStencilState(DEPTHSTENCIL_TRANSPARENT); +} + +void D3D11Renderer::endTransparentMultiPass(void) +{ + setEnableBlendingOverride(false); + setBlendState(BLEND_DEFAULT); + setDepthStencilState(DEPTHSTENCIL_DEFAULT); +} + +void D3D11Renderer::renderDeferredLight(const RendererLight& light) +{ + RENDERER_ASSERT(0, "Not implemented!"); +} + +PxU32 D3D11Renderer::convertColor(const RendererColor& color) const +{ + return color.a << 24 | color.r << 16 | color.g << 8 | color.b; +} + +bool D3D11Renderer::isOk(void) const +{ + bool ok = (m_d3d && m_d3dDevice); +#if defined(RENDERER_WINDOWS) + if (!SampleFramework::SamplePlatform::platform()->isD3D11ok() || !m_d3dx->m_library) + { + ok = false; + } +#endif + return ok; +} + +void D3D11Renderer::addResource(D3D11RendererResource& resource) +{ + RENDERER_ASSERT(resource.m_d3dRenderer == 0, "Resource already in added to the Renderer!"); + if (resource.m_d3dRenderer == 0) + { + resource.m_d3dRenderer = this; + m_resources.push_back(&resource); + } +} + +void D3D11Renderer::removeResource(D3D11RendererResource& resource) +{ + RENDERER_ASSERT(resource.m_d3dRenderer == this, "Resource not part of this Renderer!"); + if (resource.m_d3dRenderer == this) + { + resource.m_d3dRenderer = 0; + const PxU32 numResources = (PxU32)m_resources.size(); + PxU32 foundResource = numResources; + for (PxU32 i = 0; i < numResources; ++i) + { + if (m_resources[i] == &resource) + { + foundResource = i; + break; + } + } + if (foundResource < numResources) + { + m_resources[foundResource] = m_resources.back(); + m_resources.pop_back(); + } + } +} + +void D3D11Renderer::notifyResourcesLostDevice(void) +{ + const PxU32 numResources = (PxU32)m_resources.size(); + for (PxU32 i = 0; i < numResources; ++i) + { + m_resources[i]->onDeviceLost(); + } +} + +void D3D11Renderer::notifyResourcesResetDevice(void) +{ + const PxU32 numResources = (PxU32)m_resources.size(); + for (PxU32 i = 0; i < numResources; ++i) { + m_resources[i]->onDeviceReset(); + } +} + +void D3D11Renderer::bind(RendererMaterialInstance* materialInstance) +{ + m_boundMaterial = materialInstance; +#if RENDERER_ENABLE_SHADOWS + if (m_boundMaterial && m_environment.lightShadowMap) + { + const RendererMaterial::Variable* pShadowMap = m_boundMaterial->findVariable("g_lightShadowMap", RendererMaterial::VARIABLE_SAMPLER2D); + if (pShadowMap) + { + m_boundMaterial->writeData(*pShadowMap, &m_environment.lightShadowMap); + } + } +#endif +} + +/////////////////////////////////////////////////////////////////////////////// + +static void pushRasterizer(ID3D11DeviceContext& context) +{ + gRasterizerState.push_back(NULL); + gViewport.push_back(D3D11_VIEWPORT()); + PxU32 NUM_VIEWPORTS = 1; + context.RSGetState(&gRasterizerState.back()); + context.RSGetViewports(&NUM_VIEWPORTS, &gViewport.back()); +} + +static void pushBlend(ID3D11DeviceContext& context) +{ + gBlendState.push_back(NULL); + gBlendFactor.push_back(PxVec4()); + gBlendMask.push_back(0); + context.OMGetBlendState(&gBlendState.back(), &gBlendFactor.back()[0], &gBlendMask.back()); +} + +static void pushDepthStencil(ID3D11DeviceContext& context) +{ + gDepthStencilState.push_back(NULL); + gDepthStencilMask.push_back(0); + context.OMGetDepthStencilState(&gDepthStencilState.back(), &gDepthStencilMask.back()); +} + +static void popRasterizer(ID3D11DeviceContext& context) +{ + if (!gRasterizerState.empty()) + { + context.RSSetState(gRasterizerState.back()); + dxSafeRelease(gRasterizerState.back()); + gRasterizerState.pop_back(); + } + if (!gViewport.empty()) + { + context.RSSetViewports(1, &gViewport.back()); + gViewport.pop_back(); + } +} + +static void popBlend(ID3D11DeviceContext& context) +{ + if (!gBlendState.empty()) + { + context.OMSetBlendState(gBlendState.back(), &gBlendFactor.back()[0], gBlendMask.back()); + dxSafeRelease(gBlendState.back()); + gBlendState.pop_back(); + gBlendFactor.pop_back(); + gBlendMask.pop_back(); + } +} + +static void popDepthStencil(ID3D11DeviceContext& context) +{ + if (!gDepthStencilState.empty()) + { + context.OMSetDepthStencilState(gDepthStencilState.back(), gDepthStencilMask.back()); + dxSafeRelease(gDepthStencilState.back()); + gDepthStencilState.pop_back(); + gDepthStencilMask.pop_back(); + } +} + +void D3D11Renderer::pushState(StateType stateType) +{ + if (m_d3dDeviceContext) + { + switch (stateType) + { + case STATE_BLEND: + pushBlend(*m_d3dDeviceContext); + break; + case STATE_RASTERIZER: + pushRasterizer(*m_d3dDeviceContext); + break; + case STATE_DEPTHSTENCIL: + pushDepthStencil(*m_d3dDeviceContext); + break; + default: + break; + } + } +} + +void D3D11Renderer::popState(StateType stateType) +{ + if (m_d3dDeviceContext) + { + switch (stateType) + { + case STATE_BLEND: + popBlend(*m_d3dDeviceContext); + break; + case STATE_RASTERIZER: + popRasterizer(*m_d3dDeviceContext); + break; + case STATE_DEPTHSTENCIL: + popDepthStencil(*m_d3dDeviceContext); + break; + default: + break; + } + } +} + +bool D3D11Renderer::initTexter() +{ + if (!Renderer::initTexter() || !m_d3dDevice) + { + return false; + } + + return true; +} + +void D3D11Renderer::closeTexter() +{ + Renderer::closeTexter(); +} + +void D3D11Renderer::setupTextRenderStates() +{ + if (m_d3dDeviceContext) + { + pushState(STATE_BLEND); + pushState(STATE_DEPTHSTENCIL); + pushState(STATE_RASTERIZER); + + setBlendState(BLEND_TRANSPARENT); + setDepthStencilState(DEPTHSTENCIL_DISABLED); + setRasterizerState(D3D11_FILL_SOLID, D3D11_CULL_NONE); + } +} + +void D3D11Renderer::resetTextRenderStates() +{ + if (m_d3dDeviceContext) + { + popState(STATE_RASTERIZER); + popState(STATE_DEPTHSTENCIL); + popState(STATE_BLEND); + } +} + +void D3D11Renderer::renderTextBuffer(const void* vertices, PxU32 nbVerts, const PxU16* indices, PxU32 nbIndices, RendererMaterial* material) +{ + PX_UNUSED(material); + // PT: font texture must have been selected prior to calling this function + if (m_d3dDeviceContext && m_d3dDevice && m_boundMaterial) + { + const PxU32 minMeshSize = m_currentTextMesh + 1; + if ((m_currentTextMesh + 1) > m_textVertices.size() || m_textVertices[m_currentTextMesh]->getMaxVertices() < nbVerts) + { + resizeIfSmallerThan(m_textVertices, minMeshSize, NULL); + resizeIfSmallerThan(m_textMeshes, minMeshSize, NULL); + + deleteSafe(m_textVertices[m_currentTextMesh]); + deleteSafe(m_textMeshes[m_currentTextMesh]); + + RendererVertexBufferDesc desc; + desc.maxVertices = nbVerts * 3; + desc.semanticFormats[RendererVertexBuffer::SEMANTIC_POSITION] = RendererVertexBuffer::FORMAT_FLOAT4; + desc.semanticFormats[RendererVertexBuffer::SEMANTIC_COLOR] = RendererVertexBuffer::FORMAT_COLOR_BGRA; + desc.semanticFormats[RendererVertexBuffer::SEMANTIC_TEXCOORD0] = RendererVertexBuffer::FORMAT_FLOAT2; + m_textVertices[m_currentTextMesh] = new D3D11RendererVertexBuffer(*m_d3dDevice, *m_d3dDeviceContext, desc, false); + } + if ((m_currentTextMesh + 1) > m_textIndices.size() || m_textIndices[m_currentTextMesh]->getMaxIndices() < nbIndices) + { + resizeIfSmallerThan(m_textIndices, minMeshSize, NULL); + resizeIfSmallerThan(m_textMeshes, minMeshSize, NULL); + + deleteSafe(m_textIndices[m_currentTextMesh]); + deleteSafe(m_textMeshes[m_currentTextMesh]); + + RendererIndexBufferDesc desc; + desc.maxIndices = nbIndices * 3; + desc.hint = RendererIndexBuffer::HINT_DYNAMIC; + desc.format = RendererIndexBuffer::FORMAT_UINT16; + m_textIndices[m_currentTextMesh] = new D3D11RendererIndexBuffer(*m_d3dDevice, *m_d3dDeviceContext, desc); + } + if ((m_currentTextMesh + 1) > m_textMeshes.size() || NULL == m_textMeshes[m_currentTextMesh] && m_textIndices[m_currentTextMesh] && m_textVertices[m_currentTextMesh]) + { + resizeIfSmallerThan(m_textMeshes, minMeshSize, NULL); + + RendererMeshDesc meshdesc; + meshdesc.primitives = RendererMesh::PRIMITIVE_TRIANGLES; + RendererVertexBuffer* vertexBuffer = m_textVertices[m_currentTextMesh]; + meshdesc.vertexBuffers = &vertexBuffer; + meshdesc.numVertexBuffers = 1; + meshdesc.firstVertex = 0; + meshdesc.numVertices = nbVerts; + meshdesc.indexBuffer = m_textIndices[m_currentTextMesh]; + meshdesc.firstIndex = 0; + meshdesc.numIndices = nbIndices; + m_textMeshes[m_currentTextMesh] = new D3D11RendererMesh(*this, meshdesc); + } + + if (m_textMeshes[m_currentTextMesh]) + { + // Assign the vertex transform and bind to the pipeline + const RendererMaterial::Variable* pViewVariable = m_boundMaterial->findVariable("g_viewMatrix2D", RendererMaterial::VARIABLE_FLOAT4x4); + RENDERER_ASSERT(pViewVariable, "Unable to locate view matrix variable in text vertex shader."); + if (pViewVariable) + { + PxMat44 viewMatrix (PxVec4(2.f / m_displayWidth , 0, 0, -1), + PxVec4(0, -2.f / m_displayHeight, 0, 1), + PxVec4(0 , 0, 1, 0), + PxVec4(0 , 0, 0, 1)); + m_boundMaterial->writeData(*pViewVariable, &viewMatrix); + static_cast<D3D11RendererMaterial&>(m_boundMaterial->getMaterial()).bindMeshState(false); + } + memcpy(m_textVertices[m_currentTextMesh]->internalLock(D3D11_MAP_WRITE_DISCARD), vertices, nbVerts * sizeof(TextVertex)); + m_textVertices[m_currentTextMesh]->unlock(); + memcpy(m_textIndices[m_currentTextMesh]->internalLock(D3D11_MAP_WRITE_DISCARD), indices, nbIndices * sizeof(PxU16)); + m_textIndices[m_currentTextMesh]->unlock(); + + m_textMeshes[m_currentTextMesh]->setNumVerticesAndIndices(nbVerts, nbIndices); + m_textMeshes[m_currentTextMesh]->bind(); + m_textMeshes[m_currentTextMesh]->render(&m_boundMaterial->getMaterial()); + ++m_currentTextMesh; + } + } +} + +bool D3D11Renderer::isSpriteRenderingSupported(void) const +{ + if(getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) + { + return false; + } + else + { + return true; + } +} + +void D3D11Renderer::renderLines2D(const void* vertices, PxU32 nbVerts) +{ + if (m_d3dDeviceContext && m_d3dDevice && m_boundMaterial) + { + if (!m_linesVertices || m_linesVertices->getMaxVertices() < nbVerts) + { + deleteSafe(m_linesVertices); + deleteSafe(m_linesMesh); + + RendererVertexBufferDesc desc; + desc.maxVertices = nbVerts * 3; + desc.semanticFormats[RendererVertexBuffer::SEMANTIC_POSITION] = RendererVertexBuffer::FORMAT_FLOAT4; + desc.semanticFormats[RendererVertexBuffer::SEMANTIC_COLOR] = RendererVertexBuffer::FORMAT_COLOR_BGRA; + desc.semanticFormats[RendererVertexBuffer::SEMANTIC_TEXCOORD0] = RendererVertexBuffer::FORMAT_FLOAT2; + m_linesVertices = new D3D11RendererVertexBuffer(*m_d3dDevice, *m_d3dDeviceContext, desc, false); + } + if (!m_linesMesh && m_linesVertices) + { + RendererMeshDesc meshdesc; + meshdesc.primitives = RendererMesh::PRIMITIVE_LINE_STRIP; + RendererVertexBuffer* vertexBuffer = m_linesVertices; + meshdesc.vertexBuffers = &vertexBuffer; + meshdesc.numVertexBuffers = 1; + meshdesc.firstVertex = 0; + meshdesc.numVertices = nbVerts; + m_linesMesh = new D3D11RendererMesh(*this, meshdesc); + } + + if (m_linesMesh) + { + const RendererMaterial::Variable* pViewVariable = m_boundMaterial->findVariable("g_viewMatrix2D", RendererMaterial::VARIABLE_FLOAT4x4); + if (pViewVariable) + { + PxMat44 viewMatrix (PxVec4(2.f / m_displayWidth , 0, 0, -1), + PxVec4(0, -2.f / m_displayHeight, 0, 1), + PxVec4(0 , 0, 1, 0), + PxVec4(0 , 0, 0, 1)); + m_boundMaterial->writeData(*pViewVariable, &viewMatrix); + static_cast<D3D11RendererMaterial&>(m_boundMaterial->getMaterial()).bindMeshState(false); + } + memcpy(m_linesVertices->internalLock(D3D11_MAP_WRITE_DISCARD), vertices, nbVerts * sizeof(TextVertex)); + m_linesVertices->unlock(); + + m_linesMesh->setNumVerticesAndIndices(nbVerts, 0); + m_linesMesh->bind(); + m_linesMesh->render(&m_boundMaterial->getMaterial()); + } + } +} + +void D3D11Renderer::setupScreenquadRenderStates() +{ + if (m_d3dDeviceContext) + { + pushState(STATE_DEPTHSTENCIL); + pushState(STATE_RASTERIZER); + pushState(STATE_BLEND); + + setDepthStencilState(DEPTHSTENCIL_DISABLED); + setRasterizerState(D3D11_FILL_SOLID, D3D11_CULL_NONE); + setBlendState(BLEND_TRANSPARENT); + } +} + +void D3D11Renderer::resetScreenquadRenderStates() +{ + if (m_d3dDeviceContext) + { + popState(STATE_DEPTHSTENCIL); + popState(STATE_RASTERIZER); + popState(STATE_BLEND); + } +} + +bool D3D11Renderer::captureScreen( PxU32 &width, PxU32& height, PxU32& sizeInBytes, const void*& screenshotData ) +{ + bool bSuccess = false; + + HRESULT hr; + ID3D11Resource *backbufferRes; + m_d3dRenderTargetView->GetResource(&backbufferRes); + + D3D11_TEXTURE2D_DESC texDesc; + texDesc.ArraySize = 1; + texDesc.BindFlags = 0; + texDesc.CPUAccessFlags = 0; + texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + texDesc.Width = m_displayWidth; + texDesc.Height = m_displayHeight; + texDesc.MipLevels = 1; + texDesc.MiscFlags = 0; + texDesc.SampleDesc.Count = 1; + texDesc.SampleDesc.Quality = 0; + texDesc.Usage = D3D11_USAGE_DEFAULT; + + ID3D11Texture2D *texture = NULL; + hr = m_d3dDevice->CreateTexture2D(&texDesc, 0, &texture); + + if (SUCCEEDED(hr)) + { + dxSafeRelease(m_displayBuffer); + m_d3dDeviceContext->CopyResource(texture, backbufferRes); +#if !PX_XBOXONE + hr = m_d3dx->saveTextureToMemory(m_d3dDeviceContext, texture, D3DX11_IFF_BMP, &m_displayBuffer, 0); +#endif + } + + dxSafeRelease(texture); + dxSafeRelease(backbufferRes); + + if(SUCCEEDED(hr)) + { + getWindowSize(width, height); + sizeInBytes = (physx::PxU32)m_displayBuffer->GetBufferSize(); + screenshotData = m_displayBuffer->GetBufferPointer(); + bSuccess = true; + } + return bSuccess; +} + + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11Renderer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11Renderer.h new file mode 100644 index 00000000..f716cfa6 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11Renderer.h @@ -0,0 +1,344 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#ifndef D3D11_RENDERER_H +#define D3D11_RENDERER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include <Renderer.h> +#include <vector> +#include <tuple> + +#if defined(RENDERER_DEBUG) +//#define D3D_DEBUG_INFO 1 +#endif + +#define RENDERER_ENABLE_VFACE_SCALE 1 +#define RENDERER_ENABLE_SHADOWS 0 + +#if RENDERER_ENABLE_SINGLE_PASS_LIGHTING +#define RENDERER_MAX_LIGHTS 4 +#else +#define RENDERER_MAX_LIGHTS 1 +#endif + +#define INITGUID +#pragma warning(push) +// Disable macro redefinition warnings +#pragma warning(disable: 4005) +#include <d3d11.h> +#pragma warning(pop) +#undef INITGUID + +namespace SampleRenderer +{ +class RendererDesc; +class RendererColor; + +void convertToD3D11(PxVec3& dxcolor, const RendererColor& color); +void convertToD3D11(PxVec4& dxcolor, const RendererColor& color); +void convertToD3D11(PxMat44& dxmat, const RendererProjection& mat); +void convertToD3D11(PxMat44& dxmat, const physx::PxMat44 &mat); + +class D3D11RendererVariableManager; +class D3D11RendererResourceManager; +class D3D11RendererResource; +class D3D11RendererMaterial; +class D3D11RendererMesh; +class D3D11RendererVertexBuffer; +class D3D11RendererIndexBuffer; +class D3D11RendererTexture2D; + +class D3DX11; + +class D3D11Renderer : public Renderer +{ + friend class D3D11RendererResource; + friend class D3D11RendererMesh; +public: + class D3D11ShaderEnvironment + { + friend class D3D11Renderer; + friend class D3D11RendererSpotLight; + friend class D3D11RendererDirectionalLight; + + public: + D3D11ShaderEnvironment(); + + void bindFrame() const; + void bindLight(PxU32 lightIndex = 0) const; + void bindModel() const; + void bindBones() const; + void bindFogState() const; + void bindAmbientState() const; + void bindVFaceScale() const; + + void reset(); + + protected: + PxMat44 modelMatrix; + PxMat44 modelViewMatrix; + PxMat44 modelViewProjMatrix; + + PxMat44 viewMatrix; + PxMat44 projMatrix; + PxMat44 invViewProjMatrix; + PxMat44 lightShadowMatrix; + + PxMat44 boneMatrices[RENDERER_MAX_BONES]; + PxU32 numBones; + + PxVec4 fogColorAndDistance; + + PxVec3 eyePosition; + PxVec3 eyeDirection; + + PxVec3 ambientColor; + + PxVec3 lightColor[RENDERER_MAX_LIGHTS]; + PxVec3 lightDirection[RENDERER_MAX_LIGHTS]; + PxVec3 lightPosition[RENDERER_MAX_LIGHTS]; + float lightIntensity[RENDERER_MAX_LIGHTS]; + float lightInnerRadius[RENDERER_MAX_LIGHTS]; + float lightOuterRadius[RENDERER_MAX_LIGHTS]; + float lightInnerCone[RENDERER_MAX_LIGHTS]; + float lightOuterCone[RENDERER_MAX_LIGHTS]; + int lightType[RENDERER_MAX_LIGHTS]; + mutable int numLights; + + D3D11RendererTexture2D* lightShadowMap; + + float vfs; + + D3D11RendererVariableManager* constantManager; + }; + +public: + D3D11Renderer(const RendererDesc& desc, const char* assetDir); + virtual ~D3D11Renderer(void); + + ID3D11Device* getD3DDevice(void) { return m_d3dDevice; } + ID3D11DeviceContext* getD3DDeviceContext(void) { return m_d3dDeviceContext; } + D3DX11* getD3DX11(void) { return m_d3dx; } + D3D11ShaderEnvironment& getShaderEnvironment(void) { return m_environment; } + const D3D11ShaderEnvironment& getShaderEnvironment(void) const { return m_environment; } + D3D11RendererResourceManager* getResourceManager(void) { return m_resourceManager; } + D3D11RendererVariableManager* getVariableManager(void) { return m_constantManager; } + + bool multisamplingEnabled(void) const; + bool tessellationEnabled(void) const; + bool isTessellationSupported(void) const; + +private: + bool checkResize(bool resetDevice); + +public: + void onDeviceLost(void); + void onDeviceReset(void); + +public: + // clears the offscreen buffers. + virtual void clearBuffers(void); + + // presents the current color buffer to the screen. + // returns true on device reset and if buffers need to be rewritten. + virtual bool swapBuffers(void); + + // get the device pointer (void * abstraction) + virtual void* getDevice() + { + return static_cast<void*>(getD3DDevice()); + } + + // get the window size + void getWindowSize(PxU32& width, PxU32& height) const; + + // gets a handle to the current frame's data, in bitmap format + // note: subsequent calls will invalidate any previously returned data + // return true on successful screenshot capture + bool captureScreen(PxU32 &width, PxU32& height, PxU32& sizeInBytes, const void*& screenshotData); + + D3D_FEATURE_LEVEL getFeatureLevel() const { return (D3D_FEATURE_LEVEL)m_d3dDeviceFeatureLevel; } + + virtual RendererVertexBuffer* createVertexBuffer(const RendererVertexBufferDesc& desc); + virtual RendererIndexBuffer* createIndexBuffer(const RendererIndexBufferDesc& desc); + virtual RendererInstanceBuffer* createInstanceBuffer(const RendererInstanceBufferDesc& desc); + virtual RendererTexture2D* createTexture2D(const RendererTexture2DDesc& desc); + virtual RendererTexture3D* createTexture3D(const RendererTexture3DDesc& desc); + virtual RendererTarget* createTarget(const RendererTargetDesc& desc); + virtual RendererMaterial* createMaterial(const RendererMaterialDesc& desc); + virtual RendererMesh* createMesh(const RendererMeshDesc& desc); + virtual RendererLight* createLight(const RendererLightDesc& desc); + + virtual void setVsync(bool on); + + virtual bool initTexter(); + virtual void closeTexter(); + + void bind(RendererMaterialInstance* materialInstance); + + virtual bool isSpriteRenderingSupported(void) const; + +private: + virtual bool beginRender(void); + virtual void endRender(void); + virtual void bindViewProj(const physx::PxMat44& eye, const RendererProjection& proj); + virtual void bindFogState(const RendererColor& fogColor, float fogDistance); + virtual void bindAmbientState(const RendererColor& ambientColor); + virtual void bindDeferredState(void); + virtual void bindMeshContext(const RendererMeshContext& context); + virtual void beginMultiPass(void); + virtual void endMultiPass(void); + virtual void beginTransparentMultiPass(void); + virtual void endTransparentMultiPass(void); + virtual void renderDeferredLight(const RendererLight& light); + virtual PxU32 convertColor(const RendererColor& color) const; + + virtual bool isOk(void) const; + + virtual void setupTextRenderStates(); + virtual void resetTextRenderStates(); + virtual void renderTextBuffer(const void* vertices, PxU32 nbVerts, const PxU16* indices, PxU32 nbIndices, RendererMaterial* material); + virtual void renderLines2D(const void* vertices, PxU32 nbVerts); + virtual void setupScreenquadRenderStates(); + virtual void resetScreenquadRenderStates(); + +public: + enum BlendState + { + BLEND_DEFAULT = 0, + BLEND_MULTIPASS, + BLEND_TRANSPARENT, + BLEND_TRANSPARENT_ALPHA_COVERAGE, + NUM_BLEND_STATES + }; + void setBlendState(BlendState state = BLEND_DEFAULT); + + void setRasterizerState(D3D11_FILL_MODE = D3D11_FILL_SOLID, D3D11_CULL_MODE = D3D11_CULL_BACK, PxI32 depthBias = 0); + + enum DepthStencilState + { + DEPTHSTENCIL_DEFAULT = 0, + DEPTHSTENCIL_DISABLED, + DEPTHSTENCIL_TRANSPARENT, + NUM_DEPTH_STENCIL_STATES + }; + void setDepthStencilState(DepthStencilState state); + + enum StateType + { + STATE_BLEND, + STATE_DEPTHSTENCIL, + STATE_RASTERIZER, + NUM_STATE_TYPES + }; + void pushState(StateType stateType); + void popState(StateType stateType); + + void setTessellationState(); + +private: + void addResource(D3D11RendererResource& resource); + void removeResource(D3D11RendererResource& resource); + void notifyResourcesLostDevice(void); + void notifyResourcesResetDevice(void); + +private: + PxU32 m_displayWidth; + PxU32 m_displayHeight; + ID3DBlob* m_displayBuffer; + bool m_vsync; + PxI32 m_multipassDepthBias; + + IDXGIFactory* m_d3d; + IDXGISwapChain* m_d3dSwapChain; + + ID3D11BlendState* m_d3dBlendStates[NUM_BLEND_STATES]; + ID3D11Device* m_d3dDevice; + ID3D11DeviceContext* m_d3dDeviceContext; + PxU32 m_d3dDeviceFeatureLevel; + ID3D11Texture2D* m_d3dDepthStencilBuffer; + ID3D11DepthStencilView* m_d3dDepthStencilView; + ID3D11DepthStencilState* m_d3dDepthStencilStates[NUM_DEPTH_STENCIL_STATES]; + ID3D11Texture2D* m_d3dRenderTargetBuffer; + ID3D11RenderTargetView* m_d3dRenderTargetView; + + std::tr1::tuple<D3D11_FILL_MODE, D3D11_CULL_MODE, int> m_boundRasterizerStateKey; + + RendererMaterialInstance* m_boundMaterial; + + std::vector<D3D11RendererMesh*> m_textMeshes; + std::vector<D3D11RendererVertexBuffer*> m_textVertices; + std::vector<D3D11RendererIndexBuffer*> m_textIndices; + PxU32 m_currentTextMesh; + D3D11RendererMesh* m_linesMesh; + D3D11RendererVertexBuffer* m_linesVertices; + + DXGI_SWAP_CHAIN_DESC m_swapChainDesc; + physx::PxMat44 m_viewMatrix; + + // non-managed resources... + std::vector<D3D11RendererResource*> m_resources; + + D3DX11* m_d3dx; + D3D11ShaderEnvironment m_environment; + D3D11RendererVariableManager* m_constantManager; + D3D11RendererResourceManager* m_resourceManager; +}; + +class D3D11RendererResource +{ + friend class D3D11Renderer; +public: + D3D11RendererResource(void) + { + m_d3dRenderer = 0; + } + + virtual ~D3D11RendererResource(void) + { + if (m_d3dRenderer) + { + m_d3dRenderer->removeResource(*this); + } + } + +public: + virtual void onDeviceLost(void) = 0; + virtual void onDeviceReset(void) = 0; + +private: + D3D11Renderer* m_d3dRenderer; +}; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererDirectionalLight.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererDirectionalLight.cpp new file mode 100644 index 00000000..16e25b1b --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererDirectionalLight.cpp @@ -0,0 +1,61 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include "D3D11RendererDirectionalLight.h" + +using namespace SampleRenderer; + +D3D11RendererDirectionalLight::D3D11RendererDirectionalLight(D3D11Renderer& renderer, const RendererDirectionalLightDesc& desc) : + RendererDirectionalLight(desc), + m_renderer(renderer) +{ + +} + +D3D11RendererDirectionalLight::~D3D11RendererDirectionalLight(void) +{ + +} + +void D3D11RendererDirectionalLight::bind(PxU32 lightIndex) const +{ + D3D11Renderer::D3D11ShaderEnvironment& shaderEnv = m_renderer.getShaderEnvironment(); + if (lightIndex < RENDERER_MAX_LIGHTS) + { + convertToD3D11(shaderEnv.lightColor[lightIndex], m_color); + shaderEnv.lightDirection[lightIndex] = m_direction; + shaderEnv.lightIntensity[lightIndex] = m_intensity; + shaderEnv.lightType[lightIndex] = RendererMaterial::PASS_DIRECTIONAL_LIGHT; + shaderEnv.bindLight(lightIndex); + } +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererDirectionalLight.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererDirectionalLight.h new file mode 100644 index 00000000..7c98e693 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererDirectionalLight.h @@ -0,0 +1,58 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#ifndef D3D11_RENDERER_DIRECTIONAL_LIGHT_H +#define D3D11_RENDERER_DIRECTIONAL_LIGHT_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include <RendererDirectionalLight.h> + +#include "D3D11Renderer.h" + +namespace SampleRenderer +{ + +class D3D11RendererDirectionalLight : public RendererDirectionalLight +{ +public: + D3D11RendererDirectionalLight(D3D11Renderer& renderer, const RendererDirectionalLightDesc& desc); + virtual ~D3D11RendererDirectionalLight(void); + + virtual void bind(void) const { bind(0); } + virtual void bind(PxU32) const; + +private: + D3D11Renderer& m_renderer; +}; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererIndexBuffer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererIndexBuffer.cpp new file mode 100644 index 00000000..5265c28e --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererIndexBuffer.cpp @@ -0,0 +1,193 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include "D3D11RendererIndexBuffer.h" +#include <RendererIndexBufferDesc.h> + +#if PX_WINDOWS +#include <task/PxTask.h> +#endif + +using namespace SampleRenderer; + +static DXGI_FORMAT getD3D11Format(RendererIndexBuffer::Format format) +{ + DXGI_FORMAT dxgiFormat = DXGI_FORMAT_UNKNOWN; + switch (format) + { + case RendererIndexBuffer::FORMAT_UINT16: + dxgiFormat = DXGI_FORMAT_R16_UINT; + break; + case RendererIndexBuffer::FORMAT_UINT32: + dxgiFormat = DXGI_FORMAT_R32_UINT; + break; + } + RENDERER_ASSERT(dxgiFormat != DXGI_FORMAT_UNKNOWN, "Unable to convert to DXGI_FORMAT."); + return dxgiFormat; +} + +D3D11RendererIndexBuffer::D3D11RendererIndexBuffer(ID3D11Device& d3dDevice, ID3D11DeviceContext& d3dDeviceContext, const RendererIndexBufferDesc& desc, bool bUseMapForLocking) : + RendererIndexBuffer(desc), + m_d3dDevice(d3dDevice), + m_d3dDeviceContext(d3dDeviceContext), + m_d3dIndexBuffer(NULL), + m_bUseMapForLocking(bUseMapForLocking && (!desc.registerInCUDA)), + m_buffer(NULL) +{ + memset(&m_d3dBufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + m_d3dBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + m_d3dBufferDesc.ByteWidth = (UINT)(getFormatByteSize(desc.format) * desc.maxIndices); + m_d3dBufferFormat = getD3D11Format(desc.format); + + if (m_bUseMapForLocking) + { + m_d3dBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + m_d3dBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + } + else + { + m_d3dBufferDesc.CPUAccessFlags = 0; + m_d3dBufferDesc.Usage = D3D11_USAGE_DEFAULT; + m_buffer = new PxU8[m_d3dBufferDesc.ByteWidth]; + memset(m_buffer, 0, sizeof(PxU8)*m_d3dBufferDesc.ByteWidth); + } + + onDeviceReset(); + + if (m_d3dIndexBuffer) + { + m_maxIndices = desc.maxIndices; + } + +} + +D3D11RendererIndexBuffer::~D3D11RendererIndexBuffer(void) +{ + if (m_d3dIndexBuffer) + { +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if (m_interopContext && m_registeredInCUDA) + { + m_registeredInCUDA = !m_interopContext->unregisterResourceInCuda(m_InteropHandle); + } +#endif + m_d3dIndexBuffer->Release(); + m_d3dIndexBuffer = NULL; + } + + delete [] m_buffer; +} + + +void D3D11RendererIndexBuffer::onDeviceLost(void) +{ + m_registeredInCUDA = false; + + if (m_d3dIndexBuffer) + { +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if (m_interopContext && m_registeredInCUDA) + { + m_registeredInCUDA = !m_interopContext->unregisterResourceInCuda(m_InteropHandle); + } +#endif + m_d3dIndexBuffer->Release(); + m_d3dIndexBuffer = 0; + } +} + +void D3D11RendererIndexBuffer::onDeviceReset(void) +{ + if (!m_d3dIndexBuffer) + { + m_d3dDevice.CreateBuffer(&m_d3dBufferDesc, NULL, &m_d3dIndexBuffer); + RENDERER_ASSERT(m_d3dIndexBuffer, "Failed to create DIRECT3D11 Index Buffer."); +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if (m_interopContext && m_d3dIndexBuffer && m_mustBeRegisteredInCUDA) + { + m_registeredInCUDA = m_interopContext->registerResourceInCudaD3D(m_InteropHandle, m_d3dIndexBuffer); + } +#endif + } +} + +void* D3D11RendererIndexBuffer::lock(void) +{ + // For now NO_OVERWRITE is the only mapping that functions properly + return internalLock(getHint() == HINT_STATIC ? /* D3D11_MAP_WRITE_DISCARD */ D3D11_MAP_WRITE_NO_OVERWRITE : D3D11_MAP_WRITE_NO_OVERWRITE); +} + +void* D3D11RendererIndexBuffer::internalLock(D3D11_MAP MapType) +{ + void* buffer = 0; + if (m_d3dIndexBuffer) + { + if (m_bUseMapForLocking) + { + D3D11_MAPPED_SUBRESOURCE mappedRead; + m_d3dDeviceContext.Map(m_d3dIndexBuffer, 0, MapType, NULL, &mappedRead); + RENDERER_ASSERT(mappedRead.pData, "Failed to lock DIRECT3D11 Index Buffer."); + buffer = mappedRead.pData; + } + else + { + buffer = m_buffer; + } + } + return buffer; +} + +void D3D11RendererIndexBuffer::unlock(void) +{ + if (m_d3dIndexBuffer) + { + if (m_bUseMapForLocking) + { + m_d3dDeviceContext.Unmap(m_d3dIndexBuffer, 0); + } + else + { + m_d3dDeviceContext.UpdateSubresource(m_d3dIndexBuffer, 0, NULL, m_buffer, m_d3dBufferDesc.ByteWidth, 0); + } + } +} + +void D3D11RendererIndexBuffer::bind(void) const +{ + m_d3dDeviceContext.IASetIndexBuffer(m_d3dIndexBuffer, m_d3dBufferFormat, 0); +} + +void D3D11RendererIndexBuffer::unbind(void) const +{ + m_d3dDeviceContext.IASetIndexBuffer(NULL, DXGI_FORMAT(), 0); +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererIndexBuffer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererIndexBuffer.h new file mode 100644 index 00000000..52d8aaf4 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererIndexBuffer.h @@ -0,0 +1,75 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#ifndef D3D11_RENDERER_INDEXBUFFER_H +#define D3D11_RENDERER_INDEXBUFFER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include <RendererIndexBuffer.h> +#include "D3D11Renderer.h" + +namespace SampleRenderer +{ + +class D3D11RendererIndexBuffer : public RendererIndexBuffer, public D3D11RendererResource +{ + friend class D3D11Renderer; +public: + D3D11RendererIndexBuffer(ID3D11Device& d3dDevice, ID3D11DeviceContext& d3dDeviceContext, const RendererIndexBufferDesc& desc, bool bUseMapForLocking = TRUE); + virtual ~D3D11RendererIndexBuffer(void); + +public: + virtual void* lock(void); + virtual void unlock(void); + +private: + virtual void bind(void) const; + virtual void unbind(void) const; + + virtual void onDeviceLost(void); + virtual void onDeviceReset(void); + + void* internalLock(D3D11_MAP MapType); + +private: + ID3D11Device& m_d3dDevice; + ID3D11DeviceContext& m_d3dDeviceContext; + ID3D11Buffer* m_d3dIndexBuffer; + D3D11_BUFFER_DESC m_d3dBufferDesc; + DXGI_FORMAT m_d3dBufferFormat; + + bool m_bUseMapForLocking; + PxU8* m_buffer; +}; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererInstanceBuffer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererInstanceBuffer.cpp new file mode 100644 index 00000000..8ee0191e --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererInstanceBuffer.cpp @@ -0,0 +1,278 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include "D3D11RendererInstanceBuffer.h" +#include <RendererInstanceBufferDesc.h> + +#if PX_WINDOWS +#include <task/PxTask.h> +#endif + +using namespace SampleRenderer; + +static D3D11_INPUT_ELEMENT_DESC buildVertexElement(LPCSTR name, UINT index, DXGI_FORMAT format, UINT inputSlot, UINT alignedByOffset, D3D11_INPUT_CLASSIFICATION inputSlotClass, UINT instanceDataStepRate) +{ + D3D11_INPUT_ELEMENT_DESC element; + element.SemanticName = name; + element.SemanticIndex = index; + element.Format = format; + element.InputSlot = inputSlot; + element.AlignedByteOffset = alignedByOffset; + element.InputSlotClass = inputSlotClass; + element.InstanceDataStepRate = instanceDataStepRate; + return element; +} + +static DXGI_FORMAT getD3DFormat(RendererInstanceBuffer::Format format) +{ + DXGI_FORMAT d3dFormat = DXGI_FORMAT_UNKNOWN; + switch (format) + { + case RendererInstanceBuffer::FORMAT_FLOAT1: + d3dFormat = DXGI_FORMAT_R32_FLOAT; + break; + case RendererInstanceBuffer::FORMAT_FLOAT2: + d3dFormat = DXGI_FORMAT_R32G32_FLOAT; + break; + case RendererInstanceBuffer::FORMAT_FLOAT3: + d3dFormat = DXGI_FORMAT_R32G32B32_FLOAT; + break; + case RendererInstanceBuffer::FORMAT_FLOAT4: + d3dFormat = DXGI_FORMAT_R32G32B32A32_FLOAT; + break; + } + RENDERER_ASSERT(d3dFormat != DXGI_FORMAT_UNKNOWN, "Invalid DIRECT3D11 vertex type."); + return d3dFormat; +} + +static void getD3DUsage(RendererInstanceBuffer::Semantic semantic, LPCSTR& usageName, PxU8& usageIndex) +{ + if (semantic >= RendererInstanceBuffer::SEMANTIC_POSITION && semantic < RendererInstanceBuffer::NUM_SEMANTICS) + { + usageName = "TEXCOORD"; + switch (semantic) + { + case RendererInstanceBuffer::SEMANTIC_POSITION: + usageIndex = RENDERER_INSTANCE_POSITION_CHANNEL; + break; + case RendererInstanceBuffer::SEMANTIC_NORMALX: + usageIndex = RENDERER_INSTANCE_NORMALX_CHANNEL; + break; + case RendererInstanceBuffer::SEMANTIC_NORMALY: + usageIndex = RENDERER_INSTANCE_NORMALY_CHANNEL; + break; + case RendererInstanceBuffer::SEMANTIC_NORMALZ: + usageIndex = RENDERER_INSTANCE_NORMALZ_CHANNEL; + break; + case RendererInstanceBuffer::SEMANTIC_VELOCITY_LIFE: + usageIndex = RENDERER_INSTANCE_VEL_LIFE_CHANNEL; + break; + case RendererInstanceBuffer::SEMANTIC_DENSITY: + usageIndex = RENDERER_INSTANCE_DENSITY_CHANNEL; + break; + case RendererInstanceBuffer::SEMANTIC_UV_OFFSET: + usageIndex = RENDERER_INSTANCE_UV_CHANNEL; + break; + case RendererInstanceBuffer::SEMANTIC_LOCAL_OFFSET: + usageIndex = RENDERER_INSTANCE_LOCAL_CHANNEL; + break; + } + } + else + { + RENDERER_ASSERT(false, "Invalid Direct3D11 instance usage."); + } +} + +D3D11RendererInstanceBuffer::D3D11RendererInstanceBuffer(ID3D11Device& d3dDevice, ID3D11DeviceContext& d3dDeviceContext, const RendererInstanceBufferDesc& desc, bool bUseMapForLocking) : + RendererInstanceBuffer(desc) + , m_d3dDevice(d3dDevice) + , m_d3dDeviceContext(d3dDeviceContext) + , m_d3dInstanceBuffer(NULL) + , m_bUseMapForLocking(bUseMapForLocking) + , m_buffer(NULL) +{ + memset(&m_d3dBufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + m_d3dBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + m_d3dBufferDesc.ByteWidth = (UINT)(desc.maxInstances * m_stride); + + if (m_bUseMapForLocking) + { + m_d3dBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + m_d3dBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + } + else + { + m_d3dBufferDesc.CPUAccessFlags = 0; + m_d3dBufferDesc.Usage = D3D11_USAGE_DEFAULT; + m_buffer = new PxU8[m_d3dBufferDesc.ByteWidth]; + memset(m_buffer, 0, sizeof(PxU8)*m_d3dBufferDesc.ByteWidth); + } + + onDeviceReset(); + + if (m_d3dInstanceBuffer) + { + m_maxInstances = desc.maxInstances; + } +} + +D3D11RendererInstanceBuffer::~D3D11RendererInstanceBuffer(void) +{ + if (m_d3dInstanceBuffer) + { +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if (m_interopContext && m_registeredInCUDA) + { + m_registeredInCUDA = !m_interopContext->unregisterResourceInCuda(m_InteropHandle); + } +#endif + m_d3dInstanceBuffer->Release(); + m_d3dInstanceBuffer = NULL; + } + + delete [] m_buffer; +} + +void D3D11RendererInstanceBuffer::addVertexElements(PxU32 streamIndex, std::vector<D3D11_INPUT_ELEMENT_DESC> &vertexElements) const +{ + for (PxU32 i = 0; i < NUM_SEMANTICS; i++) + { + Semantic semantic = (Semantic)i; + const SemanticDesc& sm = m_semanticDescs[semantic]; + if (sm.format < NUM_FORMATS) + { + PxU8 d3dUsageIndex = 0; + LPCSTR d3dUsageName = ""; + getD3DUsage(semantic, d3dUsageName, d3dUsageIndex); + vertexElements.push_back(buildVertexElement(d3dUsageName, + d3dUsageIndex, + getD3DFormat(sm.format), + streamIndex, + (UINT)sm.offset, + D3D11_INPUT_PER_INSTANCE_DATA, + 1)); + } + } +} + +void* D3D11RendererInstanceBuffer::lock(void) +{ + return internalLock(getHint() == HINT_STATIC ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE_NO_OVERWRITE); +} + +void* D3D11RendererInstanceBuffer::internalLock(D3D11_MAP MapType) +{ + void* lockedBuffer = 0; + if (m_d3dInstanceBuffer) + { + if (m_bUseMapForLocking) + { + D3D11_MAPPED_SUBRESOURCE mappedRead; + m_d3dDeviceContext.Map(m_d3dInstanceBuffer, 0, MapType, NULL, &mappedRead); + RENDERER_ASSERT(mappedRead.pData, "Failed to lock DIRECT3D11 Vertex Buffer."); + lockedBuffer = mappedRead.pData; + } + else + { + lockedBuffer = m_buffer; + } + } + return lockedBuffer; +} + +void D3D11RendererInstanceBuffer::unlock(void) +{ + if (m_d3dInstanceBuffer) + { + if (m_bUseMapForLocking) + { + m_d3dDeviceContext.Unmap(m_d3dInstanceBuffer, 0); + } + else + { + m_d3dDeviceContext.UpdateSubresource(m_d3dInstanceBuffer, 0, NULL, m_buffer, m_d3dBufferDesc.ByteWidth, 0); + } + } +} + +void D3D11RendererInstanceBuffer::bind(PxU32 streamID, PxU32 firstInstance) const +{ + if (m_d3dInstanceBuffer) + { + ID3D11Buffer* pBuffers[1] = { m_d3dInstanceBuffer }; + UINT strides[1] = { m_stride }; + UINT offsets[1] = { firstInstance* m_stride }; + m_d3dDeviceContext.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); + } +} + +void D3D11RendererInstanceBuffer::unbind(PxU32 streamID) const +{ + ID3D11Buffer* pBuffers[1] = { NULL }; + UINT strides[1] = { 0 }; + UINT offsets[1] = { 0 }; + m_d3dDeviceContext.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); +} + +void D3D11RendererInstanceBuffer::onDeviceLost(void) +{ +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if (m_interopContext && m_registeredInCUDA) + { + PX_ASSERT(m_d3dInstanceBuffer); + m_interopContext->unregisterResourceInCuda(m_InteropHandle); + } + + m_registeredInCUDA = false; +#endif + if (m_d3dInstanceBuffer) + { + m_d3dInstanceBuffer->Release(); + m_d3dInstanceBuffer = 0; + } +} + +void D3D11RendererInstanceBuffer::onDeviceReset(void) +{ + if (!m_d3dInstanceBuffer) + { + m_d3dDevice.CreateBuffer(&m_d3dBufferDesc, NULL, &m_d3dInstanceBuffer); + RENDERER_ASSERT(m_d3dInstanceBuffer, "Failed to create DIRECT3D11 Vertex Buffer."); +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if (m_interopContext && m_d3dInstanceBuffer && m_mustBeRegisteredInCUDA) + { + m_registeredInCUDA = m_interopContext->registerResourceInCudaD3D(m_InteropHandle, m_d3dInstanceBuffer); + } +#endif + } +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererInstanceBuffer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererInstanceBuffer.h new file mode 100644 index 00000000..7180bfb5 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererInstanceBuffer.h @@ -0,0 +1,74 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D11_RENDERER_INSTANCEBUFFER_H +#define D3D11_RENDERER_INSTANCEBUFFER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include <RendererInstanceBuffer.h> +#include "D3D11Renderer.h" + +namespace SampleRenderer +{ + +class D3D11RendererInstanceBuffer : public RendererInstanceBuffer, public D3D11RendererResource +{ +public: + D3D11RendererInstanceBuffer(ID3D11Device& d3dDevice, ID3D11DeviceContext& d3dDeviceContext, const RendererInstanceBufferDesc& desc, bool bUseMapForLocking = FALSE); + virtual ~D3D11RendererInstanceBuffer(void); + + void addVertexElements(PxU32 streamIndex, std::vector<D3D11_INPUT_ELEMENT_DESC> &vertexElements) const; + +protected: + virtual void* lock(void); + virtual void unlock(void); + + virtual void bind(PxU32 streamID, PxU32 firstInstance) const; + virtual void unbind(PxU32 streamID) const; + +private: + virtual void onDeviceLost(void); + virtual void onDeviceReset(void); + + void *internalLock(D3D11_MAP MapType); + +private: + ID3D11Device& m_d3dDevice; + ID3D11DeviceContext& m_d3dDeviceContext; + ID3D11Buffer* m_d3dInstanceBuffer; + D3D11_BUFFER_DESC m_d3dBufferDesc; + + bool m_bUseMapForLocking; + PxU8* m_buffer; +}; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMaterial.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMaterial.cpp new file mode 100644 index 00000000..70ccab14 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMaterial.cpp @@ -0,0 +1,729 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include "D3D11RendererMaterial.h" + +#include <RendererMaterialDesc.h> + +#include "D3D11RendererVariableManager.h" +#include "D3D11RendererTexture2D.h" +#include "D3D11RendererMemoryMacros.h" +#include "D3D11RendererResourceManager.h" +#include "D3D11RendererUtils.h" +#include "D3D11RendererTraits.h" +#include "RendererMemoryMacros.h" + +#include <stdio.h> +#include <sstream> + +#include <PsUtilities.h> + +#if !defined PX_USE_DX11_PRECOMPILED_SHADERS +#define RENDERER_ENABLE_LAYOUT_PRECACHE 1 +#endif +static D3D_FEATURE_LEVEL gFeatureLevel = D3D_FEATURE_LEVEL_9_1; + +#if RENDERER_ENABLE_LAYOUT_PRECACHE + +static bool gBonePrecached = false; +static bool gStaticPrecached = false; + +/* Cache some sensible default input layouts */ +static D3D11_INPUT_ELEMENT_DESC inputDescStaticDiffuse[4] = +{{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}}; + +static D3D11_INPUT_ELEMENT_DESC inputDescStaticDiffuseInstanced[10] = +{{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 8, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 1}, + {"TEXCOORD", 9, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1}, + {"TEXCOORD", 10, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1}, + {"TEXCOORD", 11, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1}, + {"TEXCOORD", 12, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1}, + {"TEXCOORD", 13, DXGI_FORMAT_R32G32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1}}; + +static D3D11_INPUT_ELEMENT_DESC inputDescBoneDiffuse0[3] = +{{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}}; + +static D3D11_INPUT_ELEMENT_DESC inputDescBoneDiffuse1[5] = +{{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 6, DXGI_FORMAT_R16G16B16A16_UINT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}}; + +static D3D11_INPUT_ELEMENT_DESC inputDescBoneDiffuse2[6] = +{{"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 6, DXGI_FORMAT_R16G16B16A16_UINT, 2, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}}; + +static D3D11_INPUT_ELEMENT_DESC inputDescBoneDiffuse3[4] = +{{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 6, DXGI_FORMAT_R16G16B16A16_UINT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}}; + +static D3D11_INPUT_ELEMENT_DESC inputDescBoneSimple[5] = +{{"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 6, DXGI_FORMAT_R16G16B16A16_UINT, 2, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}}; + +#endif + +using namespace SampleRenderer; + +static D3D11_BLEND getD3DBlend(RendererMaterial::BlendFunc func) +{ + D3D11_BLEND d3dBlend = D3D11_BLEND_ONE; + switch (func) + { + case RendererMaterial::BLEND_ZERO: + d3dBlend = D3D11_BLEND_ZERO; + break; + case RendererMaterial::BLEND_ONE: + d3dBlend = D3D11_BLEND_ONE; + break; + case RendererMaterial::BLEND_SRC_COLOR: + d3dBlend = D3D11_BLEND_SRC_COLOR; + break; + case RendererMaterial::BLEND_ONE_MINUS_SRC_COLOR: + d3dBlend = D3D11_BLEND_INV_SRC_COLOR; + break; + case RendererMaterial::BLEND_SRC_ALPHA: + d3dBlend = D3D11_BLEND_SRC_ALPHA; + break; + case RendererMaterial::BLEND_ONE_MINUS_SRC_ALPHA: + d3dBlend = D3D11_BLEND_INV_SRC_ALPHA; + break; + case RendererMaterial::BLEND_DST_ALPHA: + d3dBlend = D3D11_BLEND_DEST_ALPHA; + break; + case RendererMaterial::BLEND_ONE_MINUS_DST_ALPHA: + d3dBlend = D3D11_BLEND_INV_DEST_ALPHA; + break; + case RendererMaterial::BLEND_DST_COLOR: + d3dBlend = D3D11_BLEND_DEST_COLOR; + break; + case RendererMaterial::BLEND_ONE_MINUS_DST_COLOR: + d3dBlend = D3D11_BLEND_INV_DEST_COLOR; + break; + case RendererMaterial::BLEND_SRC_ALPHA_SATURATE: + d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT; + break; + } + return d3dBlend; +} + +static D3D_SHADER_MACRO getD3DDefine(const D3D11_INPUT_ELEMENT_DESC& inputDesc) +{ +#define D3D_DEFINE_NAME(a) d3dDefine.Name = PX_STRINGIZE(PX_CONCAT(USE_,a)) +#define D3D_DEFINE_NAME_2(a,b) D3D_DEFINE_NAME(PX_CONCAT(a,b)) +#define D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,b) case b: D3D_DEFINE_NAME_2(a,b); break; +#define D3D_DEFINE_NAME_WITH_INDEX(a,b) { \ + switch(b) { \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,0) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,1) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,2) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,3) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,4) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,5) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,6) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,7) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,8) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,9) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,10) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,11) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,12) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,13) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,14) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,15) \ + D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX(a,16) \ + default: D3D_DEFINE_NAME(a); break; \ + }; \ +} \ + + D3D_SHADER_MACRO d3dDefine = {"DEFAULT", "1"}; + if (_stricmp(inputDesc.SemanticName, "TEXCOORD") == 0) D3D_DEFINE_NAME_WITH_INDEX(TEXCOORD, inputDesc.SemanticIndex) + else if (_stricmp(inputDesc.SemanticName, "TANGENT") == 0) D3D_DEFINE_NAME(TANGENT); + else if (_stricmp(inputDesc.SemanticName, "POSITION") == 0) D3D_DEFINE_NAME(POSITION); + else if (_stricmp(inputDesc.SemanticName, "NORMAL") == 0) D3D_DEFINE_NAME(NORMAL); + else if (_stricmp(inputDesc.SemanticName, "COLOR") == 0) D3D_DEFINE_NAME(COLOR); + else if (_stricmp(inputDesc.SemanticName, "BONE") == 0) D3D_DEFINE_NAME(BONE); + return d3dDefine; + +#undef D3D_DEFINE_NAME +#undef D3D_DEFINE_NAME_2 +#undef D3D_CASE_INDEX_DEFINE_NAME_WITH_INDEX +#undef D3D_DEFINE_NAME_WITH_INDEX +} + +static void getD3DDefines(const char* passName, std::vector<D3D10_SHADER_MACRO>& outputDefines) +{ + if(gFeatureLevel <= D3D_FEATURE_LEVEL_9_3) + { + const D3D_SHADER_MACRO psDefines[] = + { + "RENDERER_FRAGMENT", "1", + "RENDERER_D3D11", "1", +#if RENDERER_ENABLE_SINGLE_PASS_LIGHTING + "PASS_ALL_LIGHTS", "1", + RendererMaterial::getPassName((RendererMaterial::Pass)1), RENDERER_TEXT2(1), + RendererMaterial::getPassName((RendererMaterial::Pass)2), RENDERER_TEXT2(2), + RendererMaterial::getPassName((RendererMaterial::Pass)3), RENDERER_TEXT2(3), + RendererMaterial::getPassName((RendererMaterial::Pass)4), RENDERER_TEXT2(4), + "MAX_LIGHTS", RENDERER_TEXT2(RENDERER_MAX_LIGHTS), +#else + passName, "1", +#endif + "NO_SUPPORT_DDX_DDY", "1", + "ENABLE_VFACE", "0", + "ENABLE_VFACE_SCALE", "0", + "PX_WINDOWS", "1", + "ENABLE_SHADOWS", RENDERER_TEXT2(RENDERER_ENABLE_SHADOWS), + NULL, NULL + }; + + outputDefines.resize(PX_ARRAY_SIZE(psDefines)); + //memcpy(&outputDefines[0], psDefines, sizeof(psDefines)); + for (PxU32 i = 0; i < outputDefines.size(); ++i) + { + outputDefines[i] = psDefines[i]; + } + } + else + { + const D3D_SHADER_MACRO psDefines[] = + { + "RENDERER_FRAGMENT", "1", + "RENDERER_D3D11", "1", +#if RENDERER_ENABLE_SINGLE_PASS_LIGHTING + "PASS_ALL_LIGHTS", "1", + RendererMaterial::getPassName((RendererMaterial::Pass)1), RENDERER_TEXT2(1), + RendererMaterial::getPassName((RendererMaterial::Pass)2), RENDERER_TEXT2(2), + RendererMaterial::getPassName((RendererMaterial::Pass)3), RENDERER_TEXT2(3), + RendererMaterial::getPassName((RendererMaterial::Pass)4), RENDERER_TEXT2(4), + "MAX_LIGHTS", RENDERER_TEXT2(RENDERER_MAX_LIGHTS), +#else + passName, "1", +#endif + "ENABLE_VFACE", RENDERER_TEXT2(RENDERER_ENABLE_VFACE_SCALE), + "ENABLE_VFACE_SCALE", RENDERER_TEXT2(RENDERER_ENABLE_VFACE_SCALE), + "PX_WINDOWS", "1", + "ENABLE_SHADOWS", RENDERER_TEXT2(RENDERER_ENABLE_SHADOWS), + NULL, NULL + }; + + outputDefines.resize(PX_ARRAY_SIZE(psDefines)); + //memcpy(&outputDefines[0], psDefines, sizeof(psDefines)); + for (PxU32 i = 0; i < outputDefines.size(); ++i) + { + outputDefines[i] = psDefines[i]; + } + } +} + +static const char* boolToString(bool bTrue) +{ + return bTrue ? "1" : "0"; +} + +/* +static const bool hasDisplacementSemantic(const D3D11_INPUT_ELEMENT_DESC* inputDesc, PxU32 numInputDescs) +{ + // If no input semantics were specified, enable it by default + if (NULL == inputDesc || numInputDescs == 0) + return true; + + for (PxU32 i = 0; i < numInputDescs; ++i) + { + if (strcmp(inputDesc[i].SemanticName, "TEXCOORD") == 0 && + (inputDesc[i].SemanticIndex == RENDERER_DISPLACEMENT_CHANNEL || + inputDesc[i].SemanticIndex == RENDERER_DISPLACEMENT_FLAGS_CHANNEL)) + return true; + } + return false; +} +*/ + +static void getD3DDefines(const D3D11_INPUT_ELEMENT_DESC* inputDesc, PxU32 numInputDescs, bool bTessellationEnabled, bool bInstanced, std::vector<D3D10_SHADER_MACRO>& outputDefines) +{ + PxU32 i = 0; + static const D3D_SHADER_MACRO allVsDefine = { "USE_ALL", "1" }; + static const D3D_SHADER_MACRO nullVsDefine = { NULL, NULL }; + + if(gFeatureLevel <= D3D_FEATURE_LEVEL_9_3) + { + const D3D_SHADER_MACRO baseVsDefines[] = + { + "RENDERER_VERTEX", "1", + "RENDERER_D3D11", "1", + "PX_WINDOWS", "1", + "RENDERER_INSTANCED", "0", + "RENDERER_DISPLACED", "0", + "ENABLE_VFACE", "0", + "ENABLE_VFACE_SCALE", "0", + "ENABLE_TESSELLATION", "0", + "ADAPTIVE_TESSELLATION", "0", + "SEMANTIC_TANGENT", "TANGENT", // This will prevent mapping tangent to texcoord5 and instead to the proper TANGENT semantic + }; + const int numBaseVsDefines = PX_ARRAY_SIZE(baseVsDefines); + + // Each input element description adds a define + if (inputDesc && numInputDescs > 0) outputDefines.resize(numBaseVsDefines + numInputDescs + 1); + // If there are no input element descriptions, we simply add a "USE_ALL" define + else outputDefines.resize(numBaseVsDefines + 2); + + for (; i < numBaseVsDefines; ++i) + { + outputDefines[i] = baseVsDefines[i]; + } + } + else + { + const D3D_SHADER_MACRO baseVsDefines[] = + { + "RENDERER_VERTEX", "1", + "RENDERER_D3D11", "1", + "PX_WINDOWS", "1", + "RENDERER_INSTANCED", boolToString(bInstanced), + "RENDERER_DISPLACED", boolToString(bTessellationEnabled),// && hasDisplacementSemantic(inputDesc, numInputDescs)), + "ENABLE_VFACE", RENDERER_TEXT2(RENDERER_ENABLE_VFACE_SCALE), + "ENABLE_VFACE_SCALE", RENDERER_TEXT2(RENDERER_ENABLE_VFACE_SCALE), + "ENABLE_TESSELLATION", boolToString(bTessellationEnabled), + "ADAPTIVE_TESSELLATION", boolToString(bTessellationEnabled), + "SEMANTIC_TANGENT", "TANGENT", // This will prevent mapping tangent to texcoord5 and instead to the proper TANGENT semantic + }; + const int numBaseVsDefines = PX_ARRAY_SIZE(baseVsDefines); + + // Each input element description adds a define + if (inputDesc && numInputDescs > 0) outputDefines.resize(numBaseVsDefines + numInputDescs + 1); + // If there are no input element descriptions, we simply add a "USE_ALL" define + else outputDefines.resize(numBaseVsDefines + 2); + + for (; i < numBaseVsDefines; ++i) + { + outputDefines[i] = baseVsDefines[i]; + } + } + + // If input element descriptions were provided, add the appropriate shader defines + if (inputDesc && numInputDescs > 0) + { + for (PxU32 j = 0; j < numInputDescs; ++j) + { + if (inputDesc[j].SemanticName) + outputDefines[i++] = getD3DDefine(inputDesc[j]); + } + } + // Otherwise add the default USE_ALL define + else + { + outputDefines[i++] = allVsDefine; + } + + outputDefines[i] = nullVsDefine; +} + +D3D11RendererMaterial::D3D11RendererMaterial(D3D11Renderer& renderer, const RendererMaterialDesc& desc) : + RendererMaterial(desc, renderer.getEnableMaterialCaching()), + m_renderer(renderer), + m_blendState(NULL), + m_vertexShader(NULL), + m_instancedVertexShader(NULL), + m_geometryShader(NULL), + m_hullShader(NULL), + m_domainShader(NULL) +{ + gFeatureLevel = m_renderer.getFeatureLevel(); + memset(m_fragmentPrograms, 0, sizeof(m_fragmentPrograms)); + + if (m_renderer.getD3DDevice()) + { + if (getBlending()) loadBlending(desc); + loadShaders(desc); + } +} + +D3D11RendererMaterial::~D3D11RendererMaterial(void) +{ + dxSafeRelease(m_blendState); + m_renderer.getVariableManager()->unloadVariables(this); + +} + +void D3D11RendererMaterial::setModelMatrix(const float* matrix) +{ + m_renderer.getVariableManager()->setSharedVariable("cbMesh", "g_modelMatrix", matrix); + bindMeshState(false); +} + +void D3D11RendererMaterial::bind(RendererMaterial::Pass pass, RendererMaterialInstance* materialInstance, bool instanced) const +{ + RENDERER_ASSERT(pass < NUM_PASSES, "Invalid Material Pass."); + if (m_renderer.getD3DDeviceContext() && pass < NUM_PASSES) + { + m_renderer.bind(materialInstance); + RendererMaterial::bind(pass, materialInstance, instanced); + setVariables(pass); + setBlending(pass); + setShaders(instanced, pass); + } +} + +void D3D11RendererMaterial::bindMeshState(bool instanced) const +{ + m_renderer.getVariableManager()->bind(this, D3DTypes::SHADER_VERTEX); + if (m_geometryShader) m_renderer.getVariableManager()->bind(this, D3DTypes::SHADER_GEOMETRY); + if (m_hullShader) m_renderer.getVariableManager()->bind(this, D3DTypes::SHADER_HULL); + if (m_domainShader) m_renderer.getVariableManager()->bind(this, D3DTypes::SHADER_DOMAIN); +} + +// This may not be the best place for this, but it works just fine +static ID3D11BlendState* gBlendState = NULL; +static FLOAT gBlendFactor[4] = {0., 0., 0., 0.}; +static UINT gBlendMask = 0; + +void D3D11RendererMaterial::unbind(void) const +{ + ID3D11DeviceContext* d3dDeviceContext = m_renderer.getD3DDeviceContext(); + if (d3dDeviceContext) + { + // Only reset the blend state if it was changed + if (getBlending() && m_blendState) + { + m_renderer.popState(D3D11Renderer::STATE_DEPTHSTENCIL); + d3dDeviceContext->OMSetBlendState(gBlendState, gBlendFactor, gBlendMask); + dxSafeRelease(gBlendState); + } + d3dDeviceContext->VSSetShader(NULL, NULL, 0); + d3dDeviceContext->PSSetShader(NULL, NULL, 0); + d3dDeviceContext->GSSetShader(NULL, NULL, 0); + d3dDeviceContext->HSSetShader(NULL, NULL, 0); + d3dDeviceContext->DSSetShader(NULL, NULL, 0); + } +} + +void D3D11RendererMaterial::bindVariable(Pass pass, const Variable& variable, const void* data) const +{ + D3D11Variable& var = *(D3D11Variable*)&variable; + var.bind(pass, data); +} + +void D3D11RendererMaterial::setBlending(RendererMaterial::Pass pass) const +{ + if (getBlending() && m_blendState) + { + m_renderer.pushState(D3D11Renderer::STATE_DEPTHSTENCIL); + m_renderer.setDepthStencilState(D3D11Renderer::DEPTHSTENCIL_TRANSPARENT); + + m_renderer.getD3DDeviceContext()->OMGetBlendState(&gBlendState, gBlendFactor, &gBlendMask); + m_renderer.getD3DDeviceContext()->OMSetBlendState(m_blendState, NULL, 0xffffffff); + } +} + +void D3D11RendererMaterial::setShaders(bool instanced, RendererMaterial::Pass pass) const +{ + m_renderer.getD3DDeviceContext()->VSSetShader(getVS(instanced), NULL, 0); + m_renderer.getD3DDeviceContext()->PSSetShader(getPS(pass), NULL, 0); + m_renderer.getD3DDeviceContext()->GSSetShader(getGS(), NULL, 0); + m_renderer.getD3DDeviceContext()->HSSetShader(getHS(), NULL, 0); + m_renderer.getD3DDeviceContext()->DSSetShader(getDS(), NULL, 0); +} + +void D3D11RendererMaterial::setVariables(RendererMaterial::Pass pass) const +{ + m_renderer.getVariableManager()->bind(this, D3DTypes::SHADER_PIXEL, pass); +} + +bool D3D11RendererMaterial::tessellationEnabled() const +{ + return m_renderer.tessellationEnabled() && tessellationSupported(); +} + +bool SampleRenderer::D3D11RendererMaterial::tessellationInitialized() const +{ + return (NULL != m_hullShader) && (NULL != m_domainShader); +} + +bool D3D11RendererMaterial::tessellationSupported() const +{ + return m_renderer.isTessellationSupported() && + !m_shaderNames[D3DTypes::SHADER_DOMAIN].empty() && + !m_shaderNames[D3DTypes::SHADER_HULL].empty(); +} + +bool D3D11RendererMaterial::geometryEnabled() const +{ + return m_renderer.getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0 && + !m_shaderNames[D3DTypes::SHADER_GEOMETRY].empty(); +} + +bool D3D11RendererMaterial::geometryInitialized() const +{ + return NULL != m_geometryShader; +} + +void D3D11RendererMaterial::loadBlending(const RendererMaterialDesc& desc) +{ + D3D11_BLEND_DESC blendDesc; + memset(&blendDesc, 0, sizeof(blendDesc)); + blendDesc.AlphaToCoverageEnable = m_renderer.multisamplingEnabled(); + blendDesc.IndependentBlendEnable = FALSE; + blendDesc.RenderTarget[0].BlendEnable = getBlending(); + blendDesc.RenderTarget[0].SrcBlend = getD3DBlend(getSrcBlendFunc()); + blendDesc.RenderTarget[0].DestBlend = getD3DBlend(getDstBlendFunc()); + blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + m_renderer.getD3DDevice()->CreateBlendState(&blendDesc, &m_blendState); + RENDERER_ASSERT(m_blendState, "Failed to create blend state."); +} + +void D3D11RendererMaterial::loadShaders(const RendererMaterialDesc& desc) +{ + HRESULT result = S_OK; + +#ifdef PX_USE_DX11_PRECOMPILED_SHADERS + if(gFeatureLevel < D3D_FEATURE_LEVEL_11_0) + { + m_shaderPaths[D3DTypes::SHADER_VERTEX] = std::string(m_renderer.getAssetDir()) + "compiledshaders/dx11feature9/" + desc.vertexShaderPath + ".cso"; + m_shaderNames[D3DTypes::SHADER_VERTEX] = std::string(desc.vertexShaderPath) + ".cso"; + m_shaderPaths[D3DTypes::SHADER_PIXEL] = std::string(m_renderer.getAssetDir()) + "compiledshaders/dx11feature9/" + desc.fragmentShaderPath; + m_shaderNames[D3DTypes::SHADER_PIXEL] = std::string(desc.fragmentShaderPath); + } + else + { + m_shaderPaths[D3DTypes::SHADER_VERTEX] = std::string(m_renderer.getAssetDir()) + "compiledshaders/dx11feature11/" + desc.vertexShaderPath + ".cso"; + m_shaderNames[D3DTypes::SHADER_VERTEX] = std::string(desc.vertexShaderPath) + ".cso"; + m_shaderPaths[D3DTypes::SHADER_PIXEL] = std::string(m_renderer.getAssetDir()) + "compiledshaders/dx11feature11/" + desc.fragmentShaderPath; + m_shaderNames[D3DTypes::SHADER_PIXEL] = std::string(desc.fragmentShaderPath); + + if (desc.geometryShaderPath) + { + m_shaderPaths[D3DTypes::SHADER_GEOMETRY] = std::string(m_renderer.getAssetDir()) + "compiledshaders/dx11feature11/" + desc.geometryShaderPath; + m_shaderNames[D3DTypes::SHADER_GEOMETRY] = desc.geometryShaderPath; + } + if (desc.hullShaderPath) + { + m_shaderPaths[D3DTypes::SHADER_HULL] = std::string(m_renderer.getAssetDir()) + "compiledshaders/dx11feature11/" + desc.hullShaderPath; + m_shaderNames[D3DTypes::SHADER_HULL] = desc.hullShaderPath; + } + if (desc.domainShaderPath) + { + m_shaderPaths[D3DTypes::SHADER_DOMAIN] = std::string(m_renderer.getAssetDir()) + "compiledshaders/dx11feature11/" + desc.domainShaderPath; + m_shaderNames[D3DTypes::SHADER_DOMAIN] = desc.domainShaderPath; + } + + } +#else + m_shaderPaths[D3DTypes::SHADER_VERTEX] = std::string(m_renderer.getAssetDir()) + "shaders/" + desc.vertexShaderPath; + m_shaderNames[D3DTypes::SHADER_VERTEX] = desc.vertexShaderPath; + m_shaderPaths[D3DTypes::SHADER_PIXEL] = std::string(m_renderer.getAssetDir()) + "shaders/" + desc.fragmentShaderPath; + m_shaderNames[D3DTypes::SHADER_PIXEL] = desc.fragmentShaderPath; + if (desc.geometryShaderPath) + { + m_shaderPaths[D3DTypes::SHADER_GEOMETRY] = std::string(m_renderer.getAssetDir()) + "shaders/" + desc.geometryShaderPath; + m_shaderNames[D3DTypes::SHADER_GEOMETRY] = desc.geometryShaderPath; + } + if (desc.hullShaderPath) + { + m_shaderPaths[D3DTypes::SHADER_HULL] = std::string(m_renderer.getAssetDir()) + "shaders/" + desc.hullShaderPath; + m_shaderNames[D3DTypes::SHADER_HULL] = desc.hullShaderPath; + } + if (desc.domainShaderPath) + { + m_shaderPaths[D3DTypes::SHADER_DOMAIN] = std::string(m_renderer.getAssetDir()) + "shaders/" + desc.domainShaderPath; + m_shaderNames[D3DTypes::SHADER_DOMAIN] = desc.domainShaderPath; + } +#endif + + ID3DBlob* pShaderBlob = NULL; + + D3D11ShaderLoader loader(m_renderer); + std::vector<D3D_SHADER_MACRO> vsDefines; + std::vector<D3D_SHADER_MACRO> psDefines; + + // Load vertex shader + getD3DDefines(NULL, 0, tessellationSupported(), false, vsDefines); + D3DTraits<ID3D11VertexShader>::key_type vsKey(0xffffff, m_shaderNames[D3DTypes::SHADER_VERTEX]); + result = loader.load<ID3D11VertexShader>(vsKey, getPath(D3DTypes::SHADER_VERTEX), &vsDefines[0], &m_vertexShader, &pShaderBlob); + if (SUCCEEDED(result)) m_renderer.getVariableManager()->loadVariables(this, pShaderBlob, D3DTypes::SHADER_VERTEX); + + // Load pixel shadders for each pass + for (PxU32 i = 0; i < NUM_PASSES; i++) + { + if (SUCCEEDED(result)) + { + getD3DDefines(getPassName(Pass(i)), psDefines); + std::string shaderName = m_shaderNames[D3DTypes::SHADER_PIXEL]; + const char* pixelShaderPath = getPath(D3DTypes::SHADER_PIXEL); +#ifdef PX_USE_DX11_PRECOMPILED_SHADERS + shaderName += std::string(".") + (getPassName(Pass(i))) + ".cso"; + char shaderPathCompiled[MAX_PATH]; + strcpy(shaderPathCompiled,pixelShaderPath); + strcat(shaderPathCompiled,"."); + strcat(shaderPathCompiled,getPassName(Pass(i))); + strcat(shaderPathCompiled,".cso"); + pixelShaderPath = shaderPathCompiled; +#endif + D3DTraits<ID3D11PixelShader>::key_type psKey(i, shaderName); + result = loader.load<ID3D11PixelShader>(psKey, pixelShaderPath, &psDefines[0], &m_fragmentPrograms[i], &pShaderBlob, true); + if (SUCCEEDED(result)) m_renderer.getVariableManager()->loadVariables(this, pShaderBlob, D3DTypes::SHADER_PIXEL, (Pass)i); + } + } + + // Load geometry shader + if (SUCCEEDED(result) && geometryEnabled()) + { + D3DTraits<ID3D11GeometryShader>::key_type gsKey(m_shaderNames[D3DTypes::SHADER_GEOMETRY]); + result = loader.load<ID3D11GeometryShader>(gsKey, getPath(D3DTypes::SHADER_GEOMETRY), &vsDefines[0], &m_geometryShader, &pShaderBlob); + if (SUCCEEDED(result)) m_renderer.getVariableManager()->loadVariables(this, pShaderBlob, D3DTypes::SHADER_GEOMETRY); + } + + // Load hull shader + if (SUCCEEDED(result) && tessellationSupported()) + { + D3DTraits<ID3D11HullShader>::key_type hsKey(0xffffff, m_shaderNames[D3DTypes::SHADER_HULL]); + result = loader.load<ID3D11HullShader>(hsKey, getPath(D3DTypes::SHADER_HULL), &vsDefines[0], &m_hullShader, &pShaderBlob); + if (SUCCEEDED(result)) m_renderer.getVariableManager()->loadVariables(this, pShaderBlob, D3DTypes::SHADER_HULL); + } + + // Load domain shader + if (SUCCEEDED(result) && tessellationSupported()) + { + D3DTraits<ID3D11DomainShader>::key_type dsKey(0xffffff, m_shaderNames[D3DTypes::SHADER_DOMAIN]); + result = loader.load<ID3D11DomainShader>(dsKey, getPath(D3DTypes::SHADER_DOMAIN), &vsDefines[0], &m_domainShader, &pShaderBlob); + if (SUCCEEDED(result)) m_renderer.getVariableManager()->loadVariables(this, pShaderBlob, D3DTypes::SHADER_DOMAIN); + } + +#if RENDERER_ENABLE_LAYOUT_PRECACHE +#define CACHE_VS(desc, instanced) cacheVS(desc, ARRAYSIZE(desc), D3DX11::getInputHash(desc, ARRAYSIZE(desc)), instanced) + + if (!gStaticPrecached && !strcmp(desc.vertexShaderPath, "vertex/staticmesh.cg")) + { + gStaticPrecached = true; + CACHE_VS(inputDescStaticDiffuse, false); + CACHE_VS(inputDescStaticDiffuseInstanced, true); + } + if (!gBonePrecached && !strcmp(desc.vertexShaderPath, "vertex/skeletalmesh_1bone.cg")) + { + gBonePrecached = true; + CACHE_VS(inputDescBoneDiffuse0, false); + CACHE_VS(inputDescBoneDiffuse1, false); + CACHE_VS(inputDescBoneDiffuse2, false); + CACHE_VS(inputDescBoneDiffuse3, false); + CACHE_VS(inputDescBoneSimple, false); + } +#undef CACHE_VS +#endif // RENDERER_ENABLE_LAYOUT_PRECACHE +} + +std::string D3D11RendererMaterial::getShaderNameFromInputLayout(const D3D11_INPUT_ELEMENT_DESC* inputDesc,PxU32 numInputDescs, const std::string& shaderName) const +{ + std::string outString = shaderName; + +#ifdef PX_USE_DX11_PRECOMPILED_SHADERS + // rename + if(inputDesc && numInputDescs > 0) + { + PX_ASSERT(outString.size() > 4); + outString.resize(outString.length()-4); + for (PxU32 i = 0; i < numInputDescs; i++) + { + if (inputDesc[i].SemanticName) + { + outString += "_"; + outString += &getD3DDefine(inputDesc[i]).Name[4]; + } + } + outString += ".cso"; + } +#endif + + return outString; +} + +ID3DBlob* D3D11RendererMaterial::getVSBlob(const D3D11_INPUT_ELEMENT_DESC* inputDesc, PxU32 numInputDescs, PxU64 inputDescHash, bool bInstanced) const +{ + D3D11ShaderCacher cacher(m_renderer.getResourceManager()); + D3DTraits<ID3D11VertexShader>::value_type vsValue; + if (!cacher.check<ID3D11VertexShader>(std::make_pair(inputDescHash,getShaderNameFromInputLayout(inputDesc,numInputDescs,m_shaderNames[D3DTypes::SHADER_VERTEX])), vsValue.first, vsValue.second)) + { + cacheVS(inputDesc, numInputDescs, inputDescHash, bInstanced, &vsValue.first, &vsValue.second); + } + + // In the event we had to create a new shader for the given input layout, + // we'll need to assign it as the current shader + ID3D11VertexShader*& currentShader = bInstanced ? m_instancedVertexShader : m_vertexShader; + if (currentShader != vsValue.first) + { + currentShader = vsValue.first; + m_renderer.getD3DDeviceContext()->VSSetShader(currentShader, NULL, 0); + } + + return vsValue.second; +} + +ID3DBlob* D3D11RendererMaterial::getVSBlob(const std::vector<D3D11_INPUT_ELEMENT_DESC>& inputDesc, PxU64 inputDescHash, bool bInstanced) const +{ + return getVSBlob(&inputDesc[0], (UINT)inputDesc.size(), inputDescHash, bInstanced); +} + +void D3D11RendererMaterial::cacheVS(const D3D11_INPUT_ELEMENT_DESC* inputDesc, PxU32 numInputDescs, PxU64 inputDescHash, bool bInstanced, ID3D11VertexShader** ppShader, ID3DBlob** ppBlob) const +{ + std::vector<D3D10_SHADER_MACRO> defines; + getD3DDefines(inputDesc, numInputDescs, tessellationSupported(), bInstanced, defines); + + D3DTraits<ID3D11VertexShader>::key_type vsKey(inputDescHash, getShaderNameFromInputLayout(inputDesc,numInputDescs, m_shaderNames[D3DTypes::SHADER_VERTEX])); + + D3D11ShaderLoader loader(m_renderer); + if (FAILED(loader.load<ID3D11VertexShader>(vsKey, getShaderNameFromInputLayout(inputDesc,numInputDescs,getPath(D3DTypes::SHADER_VERTEX)).c_str(), &defines[0], ppShader, ppBlob, false))) + { + RENDERER_ASSERT(0, "Error loading D3D11 layout signature."); + } +} + +#endif + diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMaterial.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMaterial.h new file mode 100644 index 00000000..c32b3c3f --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMaterial.h @@ -0,0 +1,125 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D11_RENDERER_MATERIAL_H +#define D3D11_RENDERER_MATERIAL_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include <RendererMaterial.h> + +#include "D3D11Renderer.h" +#include "D3D11RendererTraits.h" +#include "D3Dcompiler.h" + +namespace SampleRenderer +{ + +class D3D11Renderer; + +class D3D11RendererMaterial : public RendererMaterial +{ + friend class D3D11Renderer; + friend class D3D11RendererMesh; + friend class D3D11RendererVariableManager; + + typedef RendererMaterial::Variable Variable; + +public: + D3D11RendererMaterial(D3D11Renderer& renderer, const RendererMaterialDesc& desc); + virtual ~D3D11RendererMaterial(void); + virtual void setModelMatrix(const float* matrix); + + bool tessellationEnabled() const; + bool tessellationInitialized() const; + bool tessellationSupported() const; + + bool geometryEnabled() const; + bool geometryInitialized() const; + +private: + virtual const Renderer& getRenderer() const { return m_renderer; } + virtual void bind(RendererMaterial::Pass pass, RendererMaterialInstance* materialInstance, bool instanced) const; + virtual void bindMeshState(bool instanced) const; + virtual void unbind(void) const; + virtual void bindVariable(Pass pass, const Variable& variable, const void* data) const; + +private: + typedef RendererMaterial::Variable D3D11BaseVariable; + class D3D11Variable : public D3D11BaseVariable + { + public: + D3D11Variable(const char* name, RendererMaterial::VariableType type, PxU32 offset) + : Variable(name, type, offset) { } + virtual void bind(RendererMaterial::Pass pass, const void* data) = 0; + }; + +private: + D3D11RendererMaterial& operator=(const D3D11RendererMaterial&) { return *this;} + + ID3D11VertexShader* getVS(bool bInstanced) const { return bInstanced ? m_instancedVertexShader : m_vertexShader; } + ID3D11PixelShader* getPS(RendererMaterial::Pass pass) const { return m_fragmentPrograms[pass]; } + ID3D11GeometryShader* getGS() const { return geometryEnabled() ? m_geometryShader : NULL; } + ID3D11HullShader* getHS() const { return tessellationEnabled() ? m_hullShader : NULL; } + ID3D11DomainShader* getDS() const { return tessellationEnabled() ? m_domainShader : NULL; } + + ID3DBlob* getVSBlob(const std::vector<D3D11_INPUT_ELEMENT_DESC>& inputDesc, PxU64 inputDescHash, bool bInstanced) const; + ID3DBlob* getVSBlob(const D3D11_INPUT_ELEMENT_DESC* inputDesc, PxU32 numInputDescs, PxU64 inputDescHash, bool bInstanced) const; + + const char* getPath(const D3DType type) const { return m_shaderPaths[type].c_str(); } + + void cacheVS(const D3D11_INPUT_ELEMENT_DESC* inputDesc, PxU32 numInputDescs, PxU64 inputDescHash, bool bInstanced, ID3D11VertexShader** ppShader = NULL, ID3DBlob** ppBlob = NULL) const; + std::string getShaderNameFromInputLayout(const D3D11_INPUT_ELEMENT_DESC* inputDesc, PxU32 numInputDescs,const std::string& shaderName) const; + + void setVariables(RendererMaterial::Pass pass) const; + void setBlending(RendererMaterial::Pass pass) const; + void setShaders(bool bInstanced, RendererMaterial::Pass pass) const; + + void loadBlending(const RendererMaterialDesc& desc); + void loadShaders(const RendererMaterialDesc& desc); + +private: + D3D11Renderer& m_renderer; + + ID3D11BlendState* m_blendState; + + mutable ID3D11VertexShader* m_vertexShader; + mutable ID3D11VertexShader* m_instancedVertexShader; + ID3D11GeometryShader* m_geometryShader; + ID3D11HullShader* m_hullShader; + ID3D11DomainShader* m_domainShader; + ID3D11PixelShader* m_fragmentPrograms[NUM_PASSES]; + + std::string m_shaderNames[D3DTypes::NUM_SHADER_TYPES]; + std::string m_shaderPaths[D3DTypes::NUM_SHADER_TYPES]; +}; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMemoryMacros.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMemoryMacros.h new file mode 100644 index 00000000..29640f6b --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMemoryMacros.h @@ -0,0 +1,61 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#ifndef D3D11_RENDERER_MEMORY_MACROS_H +#define D3D11_RENDERER_MEMORY_MACROS_H + +namespace SampleRenderer +{ + +template<class T> +PX_INLINE void dxSafeRelease( T*& t ) { if(t) { t->Release(); t = NULL; } } + +template<class T> +PX_INLINE void deleteSafe( T*& t ) { if(t) { delete t; t = NULL; } } + +template<class T> +PX_INLINE bool deleteAndReturnTrue( T& t ) { deleteSafe(t); return true; } + +template<class T> +PX_INLINE bool dxReleaseAndReturnTrue( T& t ) { dxSafeRelease(t); return true; } + +template<class T> +PX_INLINE void deleteAll( T& t ) { std::remove_if(t.begin(), t.end(), deleteAndReturnTrue<typename T::value_type>); }; + +template<class T> +PX_INLINE void dxSafeReleaseAll( T& t ) { std::remove_if(t.begin(), t.end(), dxReleaseAndReturnTrue<typename T::value_type>); }; + +template<class T> +PX_INLINE void resizeIfSmallerThan( T& t, typename T::size_type s, typename T::value_type v = typename T::value_type() ) +{ + if (s > t.size()) + t.resize(s, v); +} + +} + +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMesh.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMesh.cpp new file mode 100644 index 00000000..493b9850 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMesh.cpp @@ -0,0 +1,291 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include "D3D11RendererMesh.h" +#include "D3D11RendererVertexBuffer.h" +#include "D3D11RendererInstanceBuffer.h" +#include "D3D11RendererMemoryMacros.h" +#include "D3D11RendererMaterial.h" +#include "D3D11RendererUtils.h" +#include "D3D11RendererResourceManager.h" +#include "D3D11RendererVariableManager.h" + +#include <RendererMeshDesc.h> + +#include <SamplePlatform.h> + +#pragma warning(disable:4702 4189) + +using namespace SampleRenderer; + +D3D11RendererMesh::D3D11RendererMesh(D3D11Renderer& renderer, const RendererMeshDesc& desc) : + RendererMesh(desc), + m_renderer(renderer), + m_inputHash(0), + m_instancedInputHash(0), + m_bPopStates(false), +#ifdef PX_USE_DX11_PRECOMPILED_SHADERS + m_spriteShaderPath(std::string(m_renderer.getAssetDir())+"compiledshaders/dx11feature11/geometry/pointsprite.cg.cso") +#else + m_spriteShaderPath(std::string(m_renderer.getAssetDir())+"shaders/vertex/pointsprite.cg") +#endif +{ + ID3D11Device* d3dDevice = m_renderer.getD3DDevice(); + RENDERER_ASSERT(d3dDevice, "Renderer's D3D Device not found!"); + if (d3dDevice) + { + PxU32 numVertexBuffers = getNumVertexBuffers(); + const RendererVertexBuffer* const* vertexBuffers = getVertexBuffers(); + + for (PxU32 i = 0; i < numVertexBuffers; i++) + { + const RendererVertexBuffer* vb = vertexBuffers[i]; + if (vb) + { + const D3D11RendererVertexBuffer& d3dVb = *static_cast<const D3D11RendererVertexBuffer*>(vb); + d3dVb.addVertexElements(i, m_inputDescriptions); + } + } + m_inputHash = D3DX11::getInputHash(m_inputDescriptions); + + m_instancedInputDescriptions = m_inputDescriptions; + if (m_instanceBuffer) + { + static_cast<const D3D11RendererInstanceBuffer*>(m_instanceBuffer)->addVertexElements(numVertexBuffers, m_instancedInputDescriptions); + m_instancedInputHash = D3DX11::getInputHash(m_instancedInputDescriptions); + } + else + { + m_instancedInputHash = m_inputHash; + } + } +} + +D3D11RendererMesh::~D3D11RendererMesh(void) +{ + +} + +static D3D_PRIMITIVE_TOPOLOGY getD3DPrimitive(const RendererMesh::Primitive& primitive, bool bTessellationEnabled) +{ + D3D_PRIMITIVE_TOPOLOGY d3dPrimitive = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; + switch (primitive) + { + case RendererMesh::PRIMITIVE_POINTS: + d3dPrimitive = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; + break; + case RendererMesh::PRIMITIVE_LINES: + d3dPrimitive = D3D_PRIMITIVE_TOPOLOGY_LINELIST; + break; + case RendererMesh::PRIMITIVE_LINE_STRIP: + d3dPrimitive = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; + break; + case RendererMesh::PRIMITIVE_TRIANGLES: + d3dPrimitive = bTessellationEnabled ? D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST : D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + break; + case RendererMesh::PRIMITIVE_TRIANGLE_STRIP: + d3dPrimitive = bTessellationEnabled ? D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST : D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + break; + case RendererMesh::PRIMITIVE_POINT_SPRITES: + d3dPrimitive = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; + break; + } + RENDERER_ASSERT(d3dPrimitive != D3D_PRIMITIVE_TOPOLOGY_UNDEFINED, "Unable to find DIRECT3D11 Primitive."); + return d3dPrimitive; +} + +class D3D11RendererMesh::ScopedMeshRender { +public: + + ScopedMeshRender(const D3D11RendererMesh& mesh_, RendererMaterial* material, bool instanced) : mesh(mesh_) + { + mesh.setTopology(mesh.getPrimitives(), static_cast<D3D11RendererMaterial*>(material)->tessellationEnabled()); + mesh.setLayout(material, instanced); + if (mesh.getPrimitives() == RendererMesh::PRIMITIVE_POINT_SPRITES) + mesh.setSprites(true); + } + + ~ScopedMeshRender() + { + if (mesh.getPrimitives() == RendererMesh::PRIMITIVE_POINT_SPRITES) + mesh.setSprites(false); + } + + ScopedMeshRender& operator=(const ScopedMeshRender&) { return *this; } + + const D3D11RendererMesh& mesh; +}; + +void D3D11RendererMesh::renderIndices(PxU32 numVertices, PxU32 firstIndex, PxU32 numIndices, RendererIndexBuffer::Format indexFormat, RendererMaterial* material) const +{ + ID3D11DeviceContext* d3dDeviceContext = m_renderer.getD3DDeviceContext(); + RENDERER_ASSERT(material, "Invalid RendererMaterial"); + if (d3dDeviceContext && material) + { + ScopedMeshRender renderScope(*this, material, false); + d3dDeviceContext->DrawIndexed(numIndices, firstIndex, 0); + } +} + +void D3D11RendererMesh::renderVertices(PxU32 numVertices, RendererMaterial* material) const +{ + ID3D11DeviceContext* d3dDeviceContext = m_renderer.getD3DDeviceContext(); + RENDERER_ASSERT(material, "Invalid RendererMaterial"); + if (d3dDeviceContext && material) + { + ScopedMeshRender renderScope(*this, material, false); + d3dDeviceContext->Draw(numVertices, 0); + } +} + +void D3D11RendererMesh::renderIndicesInstanced(PxU32 numVertices, PxU32 firstIndex, PxU32 numIndices, RendererIndexBuffer::Format indexFormat, RendererMaterial* material) const +{ + ID3D11DeviceContext* d3dDeviceContext = m_renderer.getD3DDeviceContext(); + RENDERER_ASSERT(material, "Invalid RendererMaterial"); + if (d3dDeviceContext && material) + { + ScopedMeshRender renderScope(*this, material, true); + d3dDeviceContext->DrawIndexedInstanced(numIndices, m_numInstances, firstIndex, 0, m_firstInstance); + } +} + +void D3D11RendererMesh::renderVerticesInstanced(PxU32 numVertices, RendererMaterial* material) const +{ + ID3D11DeviceContext* d3dDeviceContext = m_renderer.getD3DDeviceContext(); + RENDERER_ASSERT(material, "Invalid RendererMaterial"); + if (d3dDeviceContext && material) + { + ScopedMeshRender renderScope(*this, material, true); + d3dDeviceContext->DrawInstanced(numVertices, m_numInstances, 0, m_firstInstance); + } +} + +void D3D11RendererMesh::bind(void) const +{ + RendererMesh::bind(); +} + +void D3D11RendererMesh::render(RendererMaterial* material) const +{ + RendererMesh::render(material); +} + +void D3D11RendererMesh::setTopology(const Primitive& primitive, bool bTessellationEnabled) const +{ + ID3D11DeviceContext* d3dContext = m_renderer.getD3DDeviceContext(); + RENDERER_ASSERT(d3dContext, "Invalid D3D11 context"); + d3dContext->IASetPrimitiveTopology(getD3DPrimitive(primitive, bTessellationEnabled)); +} + +ID3D11InputLayout* D3D11RendererMesh::getInputLayoutForMaterial(const D3D11RendererMaterial* pMaterial, bool bInstanced) const +{ + ID3D11InputLayout* pLayout = NULL; + + RENDERER_ASSERT(pMaterial, "Invalid D3D11 Material"); + const LayoutVector& inputDescriptions = bInstanced ? m_instancedInputDescriptions : m_inputDescriptions; + const PxU64& inputHash = bInstanced ? m_instancedInputHash : m_inputHash; + ID3DBlob* pVSBlob = pMaterial->getVSBlob(inputDescriptions, inputHash, bInstanced); + RENDERER_ASSERT(pVSBlob, "Invalid D3D11 Shader Blob"); + + D3DTraits<ID3D11InputLayout>::key_type ilKey(inputHash, pVSBlob); + pLayout = m_renderer.getResourceManager()->hasResource<ID3D11InputLayout>(ilKey); + if (!pLayout) + { + ID3D11Device* d3dDevice = m_renderer.getD3DDevice(); + RENDERER_ASSERT(d3dDevice, "Invalid D3D11 device"); + HRESULT result = d3dDevice->CreateInputLayout(&inputDescriptions[0], + (UINT)inputDescriptions.size(), + pVSBlob->GetBufferPointer(), + pVSBlob->GetBufferSize(), + &pLayout); + RENDERER_ASSERT(SUCCEEDED(result) && pLayout, "Failed to create DIRECT3D11 Input Layout."); + if (SUCCEEDED(result) && pLayout) + { + m_renderer.getResourceManager()->registerResource<ID3D11InputLayout>(ilKey, pLayout); + } + } + + RENDERER_ASSERT(pLayout, "Failed to find DIRECT3D11 Input Layout."); + return pLayout; +} + +void D3D11RendererMesh::setLayout(const RendererMaterial* pMaterial, bool bInstanced) const +{ + ID3D11DeviceContext* d3dContext = m_renderer.getD3DDeviceContext(); + RENDERER_ASSERT(d3dContext, "Invalid D3D11 context"); + ID3D11InputLayout* pLayout = getInputLayoutForMaterial(static_cast<const D3D11RendererMaterial*>(pMaterial), bInstanced); + d3dContext->IASetInputLayout(pLayout); +} + +void D3D11RendererMesh::setSprites(bool bEnabled) const +{ + if (bEnabled && m_renderer.getFeatureLevel() > D3D_FEATURE_LEVEL_9_3) + { + static const D3D_SHADER_MACRO geometryDefines[] = + { + "RENDERER_GEOMETRY", "1", + "RENDERER_D3D11", "1", + "PX_WINDOWS", "1", + "USE_ALL", "1", + "SEMANTIC_TANGENT", "TANGENT", + NULL, NULL + }; + + ID3D11GeometryShader* pShader = NULL; + ID3DBlob* pBlob = NULL; + bool bLoadedFromCache = false; + + D3D11ShaderLoader gsLoader(m_renderer); + if (SUCCEEDED(gsLoader.load("pointsprite", m_spriteShaderPath.c_str(), geometryDefines, &pShader, &pBlob, true, &bLoadedFromCache))) + { + // If the shader was just compiled we need to load the proper variables for it + if (!bLoadedFromCache) + { + m_renderer.getVariableManager()->loadSharedVariables(this, pBlob, D3DTypes::SHADER_GEOMETRY); + } + m_renderer.getVariableManager()->bind(this, D3DTypes::SHADER_GEOMETRY); + m_renderer.getD3DDeviceContext()->GSSetShader(pShader, NULL, 0); + } + } + else + { + m_renderer.getD3DDeviceContext()->GSSetShader(NULL, NULL, 0); + } +} + +void D3D11RendererMesh::setNumVerticesAndIndices(PxU32 nbVerts, PxU32 nbIndices) +{ + m_numVertices = nbVerts; + m_numIndices = nbIndices; +} + + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMesh.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMesh.h new file mode 100644 index 00000000..577d7dbd --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererMesh.h @@ -0,0 +1,93 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D11_RENDERER_MESH_H +#define D3D11_RENDERER_MESH_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include <RendererMesh.h> +#include "D3D11Renderer.h" + +namespace SampleRenderer +{ +class D3D11RendererMaterial; + +class D3D11RendererMesh : public RendererMesh +{ + friend class D3D11Renderer; + +public: + D3D11RendererMesh(D3D11Renderer& renderer, const RendererMeshDesc& desc); + virtual ~D3D11RendererMesh(void); + +protected: + virtual void renderIndices(PxU32 numVertices, PxU32 firstIndex, PxU32 numIndices, RendererIndexBuffer::Format indexFormat, RendererMaterial* material) const; + virtual void renderVertices(PxU32 numVertices, RendererMaterial* material) const; + + virtual void renderIndicesInstanced(PxU32 numVertices, PxU32 firstIndex, PxU32 numIndices, RendererIndexBuffer::Format indexFormat, RendererMaterial* material) const; + virtual void renderVerticesInstanced(PxU32 numVertices, RendererMaterial* material) const; + + D3D11RendererMesh& operator=(const D3D11RendererMesh&) { return *this; } + + Renderer& renderer() { return m_renderer; } + +private: + void bind(void) const; + void render(RendererMaterial* material) const; + + void setTopology(const Primitive& primitive, bool bTessellationEnabled) const; + void setLayout(const RendererMaterial*, bool bInstanced) const; + void setSprites(bool bEnabled) const; + void setNumVerticesAndIndices(PxU32 numIndices, PxU32 numVertices); + + ID3D11InputLayout* getInputLayoutForMaterial(const D3D11RendererMaterial*, bool bInstanced) const; + +private: + class ScopedMeshRender; + friend class ScopedMeshRender; + + typedef std::vector<D3D11_INPUT_ELEMENT_DESC> LayoutVector; + + D3D11Renderer& m_renderer; + + LayoutVector m_inputDescriptions; + LayoutVector m_instancedInputDescriptions; + PxU64 m_inputHash; + PxU64 m_instancedInputHash; + + // This is merely for cleanup, and has no effect on externally visible state + mutable bool m_bPopStates; + + std::string m_spriteShaderPath; +}; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererResourceManager.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererResourceManager.h new file mode 100644 index 00000000..cb0d28c2 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererResourceManager.h @@ -0,0 +1,333 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D11_RENDERER_RESOURCE_MANAGER_H +#define D3D11_RENDERER_RESROUCE_MAANGER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include <algorithm> + +#include "D3D11RendererTraits.h" +#include "D3D11RendererMemoryMacros.h" + +namespace SampleRenderer +{ + +#define USE_ANY_AS_CONTAINER 1 +class Any +{ +public: + class Visitor; +private: + class Proxy; + +public: + Any() : mpProxy(NULL) { } + ~Any() { delete mpProxy; } + +public: + Any(const Any &other): mpProxy(other.mpProxy ? other.mpProxy->clone() : 0) { } + Any &swap(Any &rhs) { std::swap(mpProxy, rhs.mpProxy); return *this; } + Any &operator=(const Any &rhs) { Any rhsTemp(rhs); return swap(rhsTemp); } + + template<typename value_type> + Any(const value_type &value) : mpProxy(new ProxyImpl<value_type>(value)) { } + + template<typename value_type> + Any &operator=(const value_type &rhs) { Any rhsTemp(rhs); return swap(rhsTemp); } + + void assign(Proxy *otherProxy) { mpProxy = otherProxy; } + +public: + const std::type_info &type_info() const { return mpProxy ? mpProxy->type_info() : typeid(void); } + operator const void *() const { return mpProxy; } + + template<typename value_type> + bool copy_to(value_type &value) const { + const value_type *copyable = to_ptr<value_type>(); + if(copyable) value = *copyable; + return copyable; + } + template<typename value_type> + const value_type *to_ptr() const + { + return type_info() == typeid(value_type) ? &static_cast<ProxyImpl<value_type> *>(mpProxy)->mValue : 0; + } + template<typename value_type> + value_type *to_ptr() + { + return type_info() == typeid(value_type) ? &static_cast<ProxyImpl<value_type> *>(mpProxy)->mValue : 0; + } + +#if !USE_ANY_AS_CONTAINER + bool operator==(const Any& other) const { + return (mpProxy && other.mpProxy) ? (*mpProxy == *other.mpProxy) + :((!mpProxy && !other.mpProxy) ? true : false); } +#endif + + void release() { if(mpProxy) mpProxy->release(); } + //void accept(Visitor& visitor) { if (mpProxy) mpProxy->accept(visitor); } + +public: + class Visitor + { + public: + virtual void visit(Proxy& proxy) = 0; + }; + +private: + + + template<typename T> + struct Releaser { + public: + static void release(T& t) { } + }; + + template <typename T> + struct Releaser<T*> + { + public: + static void release(T*& t) { dxSafeRelease(t); } + }; + + template<typename T1,typename T2> + struct Releaser< std::pair<T1*,T2*> > + { + public: + static void release(std::pair<T1*,T2*>& t) { dxSafeRelease(t.first); dxSafeRelease(t.second); } + }; + + template<typename T1,typename T2> + struct Releaser< std::map<T1,T2> > : public Visitor + { + public: + static void release(std::map<T1,T2>& t) + { + for (typename std::map<T1,T2>::iterator it = t.begin(); it != t.end(); ++it) + { + Releaser<T2>::release(it->second); + } + } + }; + + class Proxy + { + public: + virtual const std::type_info& type_info() const = 0; + virtual Proxy *clone() const = 0; + virtual void release() = 0; +#if !USE_ANY_AS_CONTAINER + virtual bool operator<(const Proxy&) const = 0; + virtual bool operator==(const Proxy&) const = 0; +#endif + }; + template<typename value_type> + class ProxyImpl : public Proxy + { + public: + ProxyImpl(const value_type &value) : mValue(value) { } + virtual const std::type_info &type_info() const { return typeid(value_type); } + virtual Proxy *clone() const { return new ProxyImpl(mValue); } + virtual void release() { Releaser<value_type>::release(mValue); } + +#if !USE_ANY_AS_CONTAINER + virtual bool operator<(const Proxy& rhs) const { return mValue < static_cast< const ProxyImpl<value_type>& >(rhs).mValue; } + virtual bool operator==(const Proxy& rhs) const { return mValue == static_cast< const ProxyImpl<value_type>& >(rhs).mValue; } +#endif + value_type mValue; + private: + ProxyImpl &operator=(const ProxyImpl&); + }; + +public: + +#if !USE_ANY_AS_CONTAINER + struct Comp + { + bool operator()(const Any& lhs, const Any& rhs) const { return *(lhs.mpProxy) < *(rhs.mpProxy); } + }; +#endif + + // Let's us use the stack instead of calling new every time we use Any + template<typename value_type> + class Temp + { + public: + Temp(const value_type& value) : mProxy(value) { mAny.assign(&mProxy); } + ~Temp() { mAny.assign(NULL); } + + Any& operator()(void) { return mAny; } + const Any& operator()(void) const { return mAny; } + + protected: + ProxyImpl<value_type> mProxy; + Any mAny; + }; + + +private: + Proxy *mpProxy; +}; + +template<typename value_type> +value_type& any_cast(Any &operand) { + return *operand.to_ptr<value_type>(); +} + +template<typename value_type> +const value_type& any_cast(const Any &operand) { + return *operand.to_ptr<value_type>(); +} + +class D3D11RendererResourceManager +{ +public: +#if USE_ANY_AS_CONTAINER + typedef Any CacheType; +#else + typedef std::map<Any, Any, Any::Comp> CacheType; +#endif + D3D11RendererResourceManager() + { +#if USE_ANY_AS_CONTAINER + mResources[D3DTraits<ID3D11VertexShader>::getType()] = + std::map< typename D3DTraits<ID3D11VertexShader>::key_type, typename D3DTraits<ID3D11VertexShader>::value_type >(); + mResources[D3DTraits<ID3D11PixelShader>::getType()] = + std::map< typename D3DTraits<ID3D11PixelShader>::key_type, typename D3DTraits<ID3D11PixelShader>::value_type >(); + mResources[D3DTraits<ID3D11GeometryShader>::getType()] = + std::map< typename D3DTraits<ID3D11GeometryShader>::key_type, typename D3DTraits<ID3D11GeometryShader>::value_type >(); + mResources[D3DTraits<ID3D11HullShader>::getType()] = + std::map< typename D3DTraits<ID3D11HullShader>::key_type, typename D3DTraits<ID3D11HullShader>::value_type >(); + mResources[D3DTraits<ID3D11DomainShader>::getType()] = + std::map< typename D3DTraits<ID3D11DomainShader>::key_type, typename D3DTraits<ID3D11DomainShader>::value_type >(); + mResources[D3DTraits<ID3D11InputLayout>::getType()] = + std::map< typename D3DTraits<ID3D11InputLayout>::key_type, typename D3DTraits<ID3D11InputLayout>::value_type >(); + mResources[D3DTraits<ID3D11RasterizerState>::getType()] = + std::map< typename D3DTraits<ID3D11RasterizerState>::key_type, typename D3DTraits<ID3D11RasterizerState>::value_type >(); + mResources[D3DTraits<ID3D11DepthStencilState>::getType()] = + std::map< typename D3DTraits<ID3D11DepthStencilState>::key_type, typename D3DTraits<ID3D11DepthStencilState>::value_type >(); + mResources[D3DTraits<ID3D11BlendState>::getType()] = + std::map< typename D3DTraits<ID3D11BlendState>::key_type, typename D3DTraits<ID3D11BlendState>::value_type >(); +#endif + } + ~D3D11RendererResourceManager() + { +#if USE_ANY_AS_CONTAINER + for (PxU32 i = 0; i < D3DTypes::NUM_TYPES; ++i) + { + mResources[i].release(); + } +#else + for (PxU32 i = 0; i < D3DTypes::NUM_TYPES; ++i) + { + for (CacheType::iterator it = mResources[i].begin(); + it != mResources[i].end(); + ++it) + { + it->second.release(); + } + } +#endif + } + +public: + + template<typename d3d_type> + typename D3DTraits<d3d_type>::value_type + hasResource(const typename D3DTraits<d3d_type>::key_type& key) + { + typedef typename D3DTraits<d3d_type>::key_type key_type; + typedef typename D3DTraits<d3d_type>::value_type value_type; + typedef std::map<key_type,value_type> cache_type; + static const int resourceID = D3DTraits<d3d_type>::getType(); + RENDERER_ASSERT(resourceID != D3DTypes::INVALID, "Invalid D3D resource type"); +#if USE_ANY_AS_CONTAINER + RENDERER_ASSERT(!(mResources[resourceID] == Any()), "Invalid D3D resource container"); + cache_type& resources = any_cast< cache_type >(mResources[resourceID]); + typename cache_type::iterator it = resources.find(key); + return (it != resources.end()) ? it->second : NullTraits<value_type>::get(); +#else + Any::Temp<key_type> tempAny(key); + typename CacheType::iterator it = mResources[resourceID].find(tempAny()); + return (it != mResources[resourceID].end()) ? any_cast<value_type>(it->second) : NullTraits<value_type>::get(); +#endif + } + + template<typename d3d_type> + const typename D3DTraits<d3d_type>::value_type + hasResource(const typename D3DTraits<d3d_type>::key_type& key) const + { + typedef typename D3DTraits<d3d_type>::key_type key_type; + typedef typename D3DTraits<d3d_type>::value_type value_type; + typedef std::map<key_type,value_type> cache_type; + static const int resourceID = D3DTraits<d3d_type>::getType(); + RENDERER_ASSERT(resourceID != D3DTypes::INVALID, "Invalid D3D resource type"); +#if USE_ANY_AS_CONTAINER + RENDERER_ASSERT(!(mResources[resourceID] == Any()), "Invalid D3D resource container"); + const cache_type& resources = any_cast< cache_type >(mResources[resourceID]); + typename cache_type::const_iterator it = resources.find(key); + return (it != resources.end()) ? it->second : NullTraits<value_type>::get(); +#else + Any::Temp<key_type> tempAny(key); + typename CacheType::iterator it = mResources[resourceID].find(tempAny()); + return (it != mResources[resourceID].end()) ? any_cast<value_type>(it->second) : NullTraits<value_type>::get(); +#endif + } + + template<typename d3d_type> + void registerResource(const typename D3DTraits<d3d_type>::key_type& key, + const typename D3DTraits<d3d_type>::value_type& value) + { + typedef typename D3DTraits<d3d_type>::key_type key_type; + typedef typename D3DTraits<d3d_type>::value_type value_type; + typedef std::map<key_type,value_type> cache_type; + static const int resourceID = D3DTraits<d3d_type>::getType(); + RENDERER_ASSERT(resourceID != D3DTypes::INVALID, "Invalid D3D resource type"); +#if USE_ANY_AS_CONTAINER + RENDERER_ASSERT(!(mResources[resourceID] == Any()), "Invalid D3D resource container"); + cache_type& resources = any_cast< cache_type >(mResources[resourceID]); + //resources[key] = value; + resources.insert(std::make_pair(key, value)); +#else + Any::Temp<key_type> tempAny(key); + //mResources[resourceID][ tempAny() ] = value; + mResources[resourceID].insert(std::make_pair(tempAny(), value)); +#endif + } + +private: + CacheType mResources[D3DTypes::NUM_TYPES]; +}; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) + +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererSpotLight.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererSpotLight.cpp new file mode 100644 index 00000000..a2e47ae5 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererSpotLight.cpp @@ -0,0 +1,69 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include "D3D11RendererSpotLight.h" +#include "D3D11RendererTexture2D.h" + +using namespace SampleRenderer; + +D3D11RendererSpotLight::D3D11RendererSpotLight(D3D11Renderer& renderer, const RendererSpotLightDesc& desc) : + RendererSpotLight(desc), + m_renderer(renderer) +{ + +} + +D3D11RendererSpotLight::~D3D11RendererSpotLight(void) +{ + +} + +void D3D11RendererSpotLight::bind(PxU32 lightIndex) const +{ + if (lightIndex < RENDERER_MAX_LIGHTS) + { + D3D11Renderer::D3D11ShaderEnvironment& shaderEnv = m_renderer.getShaderEnvironment(); + convertToD3D11(shaderEnv.lightColor[lightIndex], m_color); + shaderEnv.lightPosition[lightIndex] = m_position; + shaderEnv.lightDirection[lightIndex] = m_direction; + shaderEnv.lightIntensity[lightIndex] = m_intensity; + shaderEnv.lightInnerRadius[lightIndex] = m_innerRadius; + shaderEnv.lightOuterRadius[lightIndex] = m_outerRadius; + shaderEnv.lightInnerCone[lightIndex] = m_innerCone; + shaderEnv.lightOuterCone[lightIndex] = m_outerCone; + shaderEnv.lightType[lightIndex] = RendererMaterial::PASS_SPOT_LIGHT; + shaderEnv.lightShadowMap = m_shadowMap ? static_cast<D3D11RendererTexture2D*>(m_shadowMap) : NULL; + buildProjectMatrix(&shaderEnv.lightShadowMatrix.column0.x, m_shadowProjection, m_shadowTransform); + shaderEnv.bindLight(lightIndex); + } +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererSpotLight.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererSpotLight.h new file mode 100644 index 00000000..ed835ada --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererSpotLight.h @@ -0,0 +1,57 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D11_RENDERER_SPOT_LIGHT_H +#define D3D11_RENDERER_SPOT_LIGHT_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include <RendererSpotLight.h> + +#include "D3D11Renderer.h" + +namespace SampleRenderer +{ + +class D3D11RendererSpotLight : public RendererSpotLight +{ +public: + D3D11RendererSpotLight(D3D11Renderer& renderer, const RendererSpotLightDesc& desc); + virtual ~D3D11RendererSpotLight(void); + + virtual void bind(void) const { bind(0); } + virtual void bind(PxU32 lightIndex) const; + +private: + D3D11Renderer& m_renderer; +}; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTarget.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTarget.cpp new file mode 100644 index 00000000..60627b1b --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTarget.cpp @@ -0,0 +1,151 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> +#include "D3D11RendererTarget.h" + +#if defined(RENDERER_ENABLE_DIRECT3D11) && defined(RENDERER_ENABLE_DIRECT3D11_TARGET) + +#include <RendererTargetDesc.h> +#include "D3D11RendererTexture2D.h" +#include "D3D11RendererMemoryMacros.h" + +using namespace SampleRenderer; + +D3D11RendererTarget::D3D11RendererTarget(ID3D11Device& d3dDevice, ID3D11DeviceContext& d3dDeviceContext, const RendererTargetDesc& desc) : + m_d3dDevice(d3dDevice), + m_d3dDeviceContext(d3dDeviceContext), + m_depthStencilSurface(NULL), + m_d3dDSV(NULL), + m_d3dLastDSV(NULL), + m_d3dRS(NULL), + m_d3dLastRS(NULL) +{ + for (PxU32 i = 0; i < desc.numTextures; i++) + { + D3D11RendererTexture2D& texture = *static_cast<D3D11RendererTexture2D*>(desc.textures[i]); + m_textures.push_back(&texture); + RENDERER_ASSERT(texture.m_d3dRTV, "Invalid render target specification"); + if (texture.m_d3dRTV) + { + m_d3dRTVs.push_back(texture.m_d3dRTV); + } + } + m_depthStencilSurface = static_cast<D3D11RendererTexture2D*>(desc.depthStencilSurface); + RENDERER_ASSERT(m_depthStencilSurface && m_depthStencilSurface->m_d3dTexture, "Invalid Target Depth Stencil Surface!"); + m_d3dDSV = m_depthStencilSurface->m_d3dDSV; + onDeviceReset(); +} + +D3D11RendererTarget::~D3D11RendererTarget(void) +{ + dxSafeRelease(m_d3dRS); +} + +void D3D11RendererTarget::bind(void) +{ + RENDERER_ASSERT(m_d3dRS && m_d3dLastDSV == NULL && m_d3dLastRTVs.size() == 0, "Render target in a bad state"); + if (m_d3dRS && !m_d3dLastDSV && m_d3dLastRTVs.size() == 0) + { + m_d3dLastRTVs.resize(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, NULL); + m_d3dLastDSV = NULL; + + m_d3dDeviceContext.OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, + &m_d3dLastRTVs[0], + &m_d3dLastDSV); + m_d3dDeviceContext.RSGetState(&m_d3dLastRS); + + static const PxF32 black[4] = {0.f, 0.f, 0.f, 0.f}; + for (PxU32 i = 0; i < m_d3dRTVs.size(); ++i) + { + m_d3dDeviceContext.ClearRenderTargetView(m_d3dRTVs[i], black); + } + m_d3dDeviceContext.ClearDepthStencilView(m_d3dDSV, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1., 0); + + m_d3dDeviceContext.OMSetRenderTargets((UINT)m_d3dRTVs.size(), &m_d3dRTVs[0], m_d3dDSV); + m_d3dDeviceContext.RSSetState(m_d3dRS); + } +} + +void D3D11RendererTarget::unbind(void) +{ + RENDERER_ASSERT(m_d3dLastDSV && m_d3dLastRTVs.size() > 0, "Render Target in a bad state."); + if (m_d3dLastDSV && m_d3dLastRTVs.size() > 0) + { + m_d3dDeviceContext.OMSetRenderTargets((UINT)m_d3dLastRTVs.size(), &m_d3dLastRTVs[0], m_d3dLastDSV); + for (PxU32 i = 0; i < m_d3dLastRTVs.size(); ++i) + { + dxSafeRelease(m_d3dLastRTVs[i]); + } + m_d3dLastRTVs.clear(); + dxSafeRelease(m_d3dLastDSV); + } + if (m_d3dLastRS) + { + m_d3dDeviceContext.RSSetState(m_d3dLastRS); + dxSafeRelease(m_d3dLastRS); + } +} + +void D3D11RendererTarget::onDeviceLost(void) +{ + RENDERER_ASSERT(m_d3dLastRS == NULL, "Render Target in bad state!"); + RENDERER_ASSERT(m_d3dRS, "Render Target in bad state!"); + dxSafeRelease(m_d3dRS); +} + +void D3D11RendererTarget::onDeviceReset(void) +{ + RENDERER_ASSERT(m_d3dRS == NULL, "Render Target in a bad state!"); + if (!m_d3dRS) + { + D3D11_RASTERIZER_DESC rasterizerDesc = + { + D3D11_FILL_SOLID, // D3D11_FILL_MODE FillMode; + D3D11_CULL_NONE, // D3D11_CULL_MODE CullMode; + FALSE, // BOOL FrontCounterClockwise; + 0, // INT DepthBias; + 0, // FLOAT DepthBiasClamp; + 1.0, // FLOAT SlopeScaledDepthBias; + TRUE, // BOOL DepthClipEnable; + FALSE, // BOOL ScissorEnable; + TRUE, // BOOL MultisampleEnable; + FALSE, // BOOL AntialiasedLineEnable; + }; + + //float depthBias = 0.0001f; + //float biasSlope = 1.58f; +#if RENDERER_ENABLE_DRESSCODE + //depthBias = dcParam("depthBias", depthBias, 0.0f, 0.01f); + //biasSlope = dcParam("biasSlope", biasSlope, 0.0f, 5.0f); +#endif + + m_d3dDevice.CreateRasterizerState(&rasterizerDesc, &m_d3dRS); + } +} + +#endif //#if defined(RENDERER_ENABLE_DIRECT3D11) && defined(RENDERER_ENABLE_DIRECT3D11_TARGET) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTarget.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTarget.h new file mode 100644 index 00000000..efa8bd53 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTarget.h @@ -0,0 +1,80 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D11_RENDERER_TARGET_H +#define D3D11_RENDERER_TARGET_H + +#include <RendererConfig.h> + +#if defined(RENDERER_WINDOWS) +#define RENDERER_ENABLE_DIRECT3D11_TARGET +#endif + +#if defined(RENDERER_ENABLE_DIRECT3D11) && defined(RENDERER_ENABLE_DIRECT3D11_TARGET) + +#include <RendererTarget.h> +#include "D3D11Renderer.h" + +namespace SampleRenderer +{ +class D3D11RendererTexture2D; + +class D3D11RendererTarget : public RendererTarget, public D3D11RendererResource +{ +public: + D3D11RendererTarget(ID3D11Device& d3dDevice, ID3D11DeviceContext& d3dDeviceContext, const RendererTargetDesc& desc); + virtual ~D3D11RendererTarget(void); + +private: + D3D11RendererTarget& operator=(const D3D11RendererTarget&) {} + virtual void bind(void); + virtual void unbind(void); + +private: + virtual void onDeviceLost(void); + virtual void onDeviceReset(void); + +private: + ID3D11Device& m_d3dDevice; + ID3D11DeviceContext& m_d3dDeviceContext; + + std::vector<D3D11RendererTexture2D*> m_textures; + D3D11RendererTexture2D* m_depthStencilSurface; + + std::vector<ID3D11RenderTargetView*> m_d3dRTVs; + std::vector<ID3D11RenderTargetView*> m_d3dLastRTVs; + + ID3D11DepthStencilView* m_d3dDSV; + ID3D11DepthStencilView* m_d3dLastDSV; + + ID3D11RasterizerState* m_d3dRS; + ID3D11RasterizerState* m_d3dLastRS; +}; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) && defined(RENDERER_ENABLE_DIRECT3D11_TARGET) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTexture2D.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTexture2D.cpp new file mode 100644 index 00000000..e96b8959 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTexture2D.cpp @@ -0,0 +1,300 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include "D3D11RendererTexture2D.h" +#include "D3D11RendererMemoryMacros.h" + +#include <RendererTexture2DDesc.h> + +using namespace SampleRenderer; + +D3D11RendererTexture2D::D3D11RendererTexture2D(ID3D11Device& d3dDevice, ID3D11DeviceContext& d3dDeviceContext, const RendererTexture2DDesc& desc) : + RendererTexture2D(desc), + m_d3dDevice(d3dDevice), + m_d3dDeviceContext(d3dDeviceContext), + m_d3dTexture(NULL), + m_d3dSamplerState(NULL), + m_d3dSRV(NULL), + m_d3dRTV(NULL), + m_d3dDSV(NULL) +{ + loadTextureDesc(desc); + onDeviceReset(); +} + +D3D11RendererTexture2D::~D3D11RendererTexture2D(void) +{ + dxSafeRelease(m_d3dTexture); + dxSafeRelease(m_d3dSamplerState); + dxSafeRelease(m_d3dSRV); + dxSafeRelease(m_d3dRTV); + dxSafeRelease(m_d3dDSV); + + if (m_data) + { + for (PxU32 i = 0; i < getNumLevels(); i++) + { + delete [] m_data[i]; + } + delete [] m_data; + } + if (m_resourceData) + { + delete [] m_resourceData; + } +} + +void* D3D11RendererTexture2D::lockLevel(PxU32 level, PxU32& pitch) +{ + void* buffer = 0; + RENDERER_ASSERT(level < getNumLevels(), "Level out of range!"); + if (level < getNumLevels()) + { + buffer = m_data[level]; + pitch = getFormatNumBlocks(getWidth() >> level, getFormat()) * getBlockSize(); + } + return buffer; +} + +void D3D11RendererTexture2D::unlockLevel(PxU32 level) +{ + RENDERER_ASSERT(level < getNumLevels(), "Level out of range!"); + + if (m_d3dTexture && level < getNumLevels()) + { + PxU32 w = getLevelDimension(getWidth(), level); + PxU32 h = getLevelDimension(getHeight(), level); + m_d3dDeviceContext.UpdateSubresource(m_d3dTexture, + level, + NULL, + m_data[level], + getFormatNumBlocks(w, getFormat()) * getBlockSize(), + computeImageByteSize(w, h, 1, getFormat())); + } +} + +void D3D11RendererTexture2D::bind(PxU32 samplerIndex, PxU32 flags) +{ + if (flags) + { + if (m_d3dSRV) + { + if (flags & BIND_VERTEX) + m_d3dDeviceContext.VSSetShaderResources(samplerIndex, 1, &m_d3dSRV); + if (flags & BIND_GEOMETRY) + m_d3dDeviceContext.GSSetShaderResources(samplerIndex, 1, &m_d3dSRV); + if (flags & BIND_PIXEL) + m_d3dDeviceContext.PSSetShaderResources(samplerIndex, 1, &m_d3dSRV); + if (flags & BIND_HULL) + m_d3dDeviceContext.HSSetShaderResources(samplerIndex, 1, &m_d3dSRV); + if (flags & BIND_DOMAIN) + m_d3dDeviceContext.DSSetShaderResources(samplerIndex, 1, &m_d3dSRV); + } + if (m_d3dSamplerState) + { + if (flags & BIND_VERTEX) + m_d3dDeviceContext.VSSetSamplers(samplerIndex, 1, &m_d3dSamplerState); + if (flags & BIND_GEOMETRY) + m_d3dDeviceContext.GSSetSamplers(samplerIndex, 1, &m_d3dSamplerState); + if (flags & BIND_PIXEL) + m_d3dDeviceContext.PSSetSamplers(samplerIndex, 1, &m_d3dSamplerState); + if (flags & BIND_HULL) + m_d3dDeviceContext.HSSetSamplers(samplerIndex, 1, &m_d3dSamplerState); + if (flags & BIND_DOMAIN) + m_d3dDeviceContext.DSSetSamplers(samplerIndex, 1, &m_d3dSamplerState); + } + } + else + { + ID3D11ShaderResourceView* nullResources[] = { NULL }; + m_d3dDeviceContext.VSSetShaderResources(samplerIndex, 1, nullResources); + m_d3dDeviceContext.GSSetShaderResources(samplerIndex, 1, nullResources); + m_d3dDeviceContext.PSSetShaderResources(samplerIndex, 1, nullResources); + m_d3dDeviceContext.HSSetShaderResources(samplerIndex, 1, nullResources); + m_d3dDeviceContext.DSSetShaderResources(samplerIndex, 1, nullResources); + ID3D11SamplerState* nullSamplers[] = { NULL }; + m_d3dDeviceContext.VSSetSamplers(samplerIndex, 1, nullSamplers); + m_d3dDeviceContext.GSSetSamplers(samplerIndex, 1, nullSamplers); + m_d3dDeviceContext.PSSetSamplers(samplerIndex, 1, nullSamplers); + m_d3dDeviceContext.HSSetSamplers(samplerIndex, 1, nullSamplers); + m_d3dDeviceContext.DSSetSamplers(samplerIndex, 1, nullSamplers); + } +} + +void D3D11RendererTexture2D::onDeviceLost(void) +{ + dxSafeRelease(m_d3dTexture); + dxSafeRelease(m_d3dSamplerState); + dxSafeRelease(m_d3dSRV); + dxSafeRelease(m_d3dRTV); + dxSafeRelease(m_d3dDSV); +} + +void D3D11RendererTexture2D::onDeviceReset(void) +{ + HRESULT result = S_OK; + if (!m_d3dTexture) + { + D3D11_SUBRESOURCE_DATA* pData = isDepthStencilFormat(getFormat()) ? NULL : m_resourceData; + result = m_d3dDevice.CreateTexture2D(&m_d3dTextureDesc, pData, &m_d3dTexture); + RENDERER_ASSERT(SUCCEEDED(result), "Unable to create D3D11 Texture."); + } + if (SUCCEEDED(result) && !m_d3dSamplerState) + { + result = m_d3dDevice.CreateSamplerState(&m_d3dSamplerDesc, &m_d3dSamplerState); + RENDERER_ASSERT(SUCCEEDED(result), "Unable to create D3D11 Sampler."); + } + if (SUCCEEDED(result) && m_d3dTextureDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE && !m_d3dSRV) + { + result = m_d3dDevice.CreateShaderResourceView(m_d3dTexture, &m_d3dSRVDesc, &m_d3dSRV); + RENDERER_ASSERT(SUCCEEDED(result), "Unable to create D3D11 Shader Resource View."); + } + if (SUCCEEDED(result) && m_d3dTextureDesc.BindFlags & D3D11_BIND_RENDER_TARGET && !m_d3dRTV) + { + result = m_d3dDevice.CreateRenderTargetView(m_d3dTexture, &m_d3dRTVDesc, &m_d3dRTV); + RENDERER_ASSERT(SUCCEEDED(result), "Unable to create D3D11 Render Target View."); + } + if (SUCCEEDED(result) && m_d3dTextureDesc.BindFlags & D3D11_BIND_DEPTH_STENCIL && !m_d3dDSV) + { + result = m_d3dDevice.CreateDepthStencilView(m_d3dTexture, &m_d3dDSVDesc, &m_d3dDSV); + RENDERER_ASSERT(SUCCEEDED(result), "Unable to create D3D11 Depth Stencil View."); + } +} + + +void D3D11RendererTexture2D::loadTextureDesc(const RendererTexture2DDesc& desc) +{ + RENDERER_ASSERT(desc.depth == 1, "Invalid depth for 2D Texture!"); + + //memset(&m_d3dTextureDesc, 0, sizeof(m_d3dTextureDesc)); + m_d3dTextureDesc = D3D11_TEXTURE2D_DESC(); + m_d3dTextureDesc.Width = getWidth(); + m_d3dTextureDesc.Height = getHeight(); + m_d3dTextureDesc.MipLevels = getNumLevels(); + m_d3dTextureDesc.ArraySize = 1; + m_d3dTextureDesc.Format = getD3D11TextureFormat(desc.format); + m_d3dTextureDesc.SampleDesc.Count = 1; + m_d3dTextureDesc.SampleDesc.Quality = 0; + m_d3dTextureDesc.CPUAccessFlags = 0; + m_d3dTextureDesc.Usage = D3D11_USAGE_DEFAULT; + m_d3dTextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + + loadResourceDesc(desc); + + if (isDepthStencilFormat(desc.format)) + { + m_d3dTextureDesc.BindFlags |= D3D11_BIND_DEPTH_STENCIL; + m_d3dTextureDesc.CPUAccessFlags = 0; + m_d3dTextureDesc.Usage = D3D11_USAGE_DEFAULT; + loadDepthStencilDesc(desc); + } + else if (desc.renderTarget) + { + m_d3dTextureDesc.BindFlags |= D3D11_BIND_RENDER_TARGET; + m_d3dTextureDesc.CPUAccessFlags = 0; + m_d3dTextureDesc.Usage = D3D11_USAGE_DEFAULT; + loadTargetDesc(desc); + } + + loadSamplerDesc(desc); + + //if (m_d3dTextureDesc.CPUAccessFlags) + { + m_data = new PxU8*[getNumLevels()]; + m_resourceData = new D3D11_SUBRESOURCE_DATA[getNumLevels()]; + memset(m_data, 0, sizeof(PxU8)*getNumLevels()); + memset(m_resourceData, 0, sizeof(D3D11_SUBRESOURCE_DATA)*getNumLevels()); + + for (PxU32 i = 0; i < desc.numLevels; i++) + { + PxU32 w = getLevelDimension(getWidth(), i); + PxU32 h = getLevelDimension(getHeight(), i); + PxU32 levelSize = computeImageByteSize(w, h, 1, desc.format); + m_data[i] = new PxU8[levelSize]; + memset(m_data[i], 0, levelSize); + m_resourceData[i].pSysMem = m_data[i]; + m_resourceData[i].SysMemPitch = levelSize / h; + m_resourceData[i].SysMemSlicePitch = 0; + } + } +} + +void D3D11RendererTexture2D::loadSamplerDesc(const RendererTexture2DDesc& desc) +{ + m_d3dSamplerDesc.Filter = getD3D11TextureFilter(desc.filter); + m_d3dSamplerDesc.AddressU = getD3D11TextureAddressing(desc.addressingU); + m_d3dSamplerDesc.AddressV = getD3D11TextureAddressing(desc.addressingV); + m_d3dSamplerDesc.AddressW = getD3D11TextureAddressing(desc.addressingW); + m_d3dSamplerDesc.MipLODBias = 0.f; + m_d3dSamplerDesc.MaxAnisotropy = 1; + m_d3dSamplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + m_d3dSamplerDesc.BorderColor[0] = m_d3dSamplerDesc.BorderColor[1] = m_d3dSamplerDesc.BorderColor[2] = m_d3dSamplerDesc.BorderColor[3] = 0.; + m_d3dSamplerDesc.MinLOD = 0; + if (desc.numLevels <= 1) + { + m_d3dSamplerDesc.MaxLOD = 0.; + } + else + { + m_d3dSamplerDesc.MaxLOD = D3D11_FLOAT32_MAX; + } + if(m_d3dDevice.GetFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) + { + m_d3dSamplerDesc.MaxLOD = D3D11_FLOAT32_MAX; + } +} + +void D3D11RendererTexture2D::loadResourceDesc(const RendererTexture2DDesc& desc) +{ + m_d3dSRVDesc.Format = (m_d3dTextureDesc.Format == DXGI_FORMAT_R16_TYPELESS) ? DXGI_FORMAT_R16_UNORM : m_d3dTextureDesc.Format; + m_d3dSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + m_d3dSRVDesc.Texture2D.MipLevels = m_d3dTextureDesc.MipLevels; + m_d3dSRVDesc.Texture2D.MostDetailedMip = 0; + //m_d3dSRVDesc.Texture2D.MostDetailedMip = m_d3dTextureDesc.MipLevels-1; +} + +void D3D11RendererTexture2D::loadTargetDesc(const RendererTexture2DDesc& desc) +{ + m_d3dRTVDesc = D3D11_RENDER_TARGET_VIEW_DESC(); + m_d3dRTVDesc.Format = (m_d3dTextureDesc.Format == DXGI_FORMAT_R16_TYPELESS) ? DXGI_FORMAT_R16_UNORM : m_d3dTextureDesc.Format; + m_d3dRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + m_d3dRTVDesc.Texture2D.MipSlice = 0; +} + +void D3D11RendererTexture2D::loadDepthStencilDesc(const RendererTexture2DDesc& desc) +{ + m_d3dDSVDesc = D3D11_DEPTH_STENCIL_VIEW_DESC(); + m_d3dDSVDesc.Format = (m_d3dTextureDesc.Format == DXGI_FORMAT_R16_TYPELESS) ? DXGI_FORMAT_D16_UNORM : m_d3dTextureDesc.Format; + m_d3dDSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + m_d3dDSVDesc.Texture2D.MipSlice = 0; +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTexture2D.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTexture2D.h new file mode 100644 index 00000000..89ac76b9 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTexture2D.h @@ -0,0 +1,96 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D11_RENDERER_TEXTURE_2D_H +#define D3D11_RENDERER_TEXTURE_2D_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include <RendererTexture2D.h> + +#include "D3D11Renderer.h" +#include "D3D11RendererTextureCommon.h" + +namespace SampleRenderer +{ + +class D3D11RendererTexture2D : public RendererTexture2D, public D3D11RendererResource +{ + friend class D3D11RendererTarget; + friend class D3D11RendererSpotLight; +public: + D3D11RendererTexture2D(ID3D11Device& d3dDevice, ID3D11DeviceContext& d3dDeviceContext, const RendererTexture2DDesc& desc); + virtual ~D3D11RendererTexture2D(void); + +public: + virtual void* lockLevel(PxU32 level, PxU32& pitch); + virtual void unlockLevel(PxU32 level); + + void bind(PxU32 samplerIndex, PxU32 flags = BIND_PIXEL); + + virtual void select(PxU32 stageIndex) + { + bind(stageIndex); + } + +private: + virtual void onDeviceLost(void); + virtual void onDeviceReset(void); + + void loadTextureDesc(const RendererTexture2DDesc&); + void loadSamplerDesc(const RendererTexture2DDesc&); + void loadResourceDesc(const RendererTexture2DDesc&); + void loadTargetDesc(const RendererTexture2DDesc&); + void loadDepthStencilDesc(const RendererTexture2DDesc&); + +private: + ID3D11Device& m_d3dDevice; + ID3D11DeviceContext& m_d3dDeviceContext; + ID3D11Texture2D* m_d3dTexture; + D3D11_TEXTURE2D_DESC m_d3dTextureDesc; + + ID3D11SamplerState* m_d3dSamplerState; + D3D11_SAMPLER_DESC m_d3dSamplerDesc; + + ID3D11ShaderResourceView* m_d3dSRV; + D3D11_SHADER_RESOURCE_VIEW_DESC m_d3dSRVDesc; + + ID3D11RenderTargetView* m_d3dRTV; + D3D11_RENDER_TARGET_VIEW_DESC m_d3dRTVDesc; + + ID3D11DepthStencilView* m_d3dDSV; + D3D11_DEPTH_STENCIL_VIEW_DESC m_d3dDSVDesc; + + PxU8** m_data; + D3D11_SUBRESOURCE_DATA* m_resourceData; +}; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTexture3D.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTexture3D.cpp new file mode 100644 index 00000000..247340a3 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTexture3D.cpp @@ -0,0 +1,247 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include "D3D11RendererTexture3D.h" +#include "D3D11RendererMemoryMacros.h" +#include "D3D11RendererTextureCommon.h" + +#include <RendererTextureDesc.h> + +using namespace SampleRenderer; + +D3D11RendererTexture3D::D3D11RendererTexture3D(ID3D11Device& d3dDevice, ID3D11DeviceContext& d3dDeviceContext, const RendererTexture3DDesc& desc) : + RendererTexture3D(desc), + m_d3dDevice(d3dDevice), + m_d3dDeviceContext(d3dDeviceContext), + m_d3dTexture(NULL), + m_d3dSamplerState(NULL), + m_d3dSRV(NULL) +{ + loadTextureDesc(desc); + onDeviceReset(); +} + +D3D11RendererTexture3D::~D3D11RendererTexture3D(void) +{ + dxSafeRelease(m_d3dTexture); + dxSafeRelease(m_d3dSamplerState); + dxSafeRelease(m_d3dSRV); + + if (m_data) + { + for (PxU32 i = 0; i < getNumLevels(); i++) + { + delete [] m_data[i]; + } + delete [] m_data; + } + if (m_resourceData) + { + delete [] m_resourceData; + } +} + +void* D3D11RendererTexture3D::lockLevel(PxU32 level, PxU32& pitch) +{ + void* buffer = 0; + RENDERER_ASSERT(level < getNumLevels(), "Level out of range!"); + if (level < getNumLevels()) + { + buffer = m_data[level]; + pitch = getFormatNumBlocks(getWidth() >> level, getFormat()) * getBlockSize(); + } + return buffer; +} + +void D3D11RendererTexture3D::unlockLevel(PxU32 level) +{ + RENDERER_ASSERT(level < getNumLevels(), "Level out of range!"); + + if (m_d3dTexture && level < getNumLevels()) + { + PxU32 w = getLevelDimension(getWidth(), level); + PxU32 h = getLevelDimension(getHeight(), level); + m_d3dDeviceContext.UpdateSubresource(m_d3dTexture, + level, + NULL, + m_data[level], + getFormatNumBlocks(w, getFormat()) * getBlockSize(), + computeImageByteSize(w, h, 1, getFormat())); + } +} + +void D3D11RendererTexture3D::bind(PxU32 samplerIndex, PxU32 flags) +{ + if (flags) + { + if (m_d3dSRV) + { + if (flags & BIND_VERTEX) + m_d3dDeviceContext.VSSetShaderResources(samplerIndex, 1, &m_d3dSRV); + if (flags & BIND_GEOMETRY) + m_d3dDeviceContext.GSSetShaderResources(samplerIndex, 1, &m_d3dSRV); + if (flags & BIND_PIXEL) + m_d3dDeviceContext.PSSetShaderResources(samplerIndex, 1, &m_d3dSRV); + if (flags & BIND_HULL) + m_d3dDeviceContext.HSSetShaderResources(samplerIndex, 1, &m_d3dSRV); + if (flags & BIND_DOMAIN) + m_d3dDeviceContext.DSSetShaderResources(samplerIndex, 1, &m_d3dSRV); + } + if (m_d3dSamplerState) + { + if (flags & BIND_VERTEX) + m_d3dDeviceContext.VSSetSamplers(samplerIndex, 1, &m_d3dSamplerState); + if (flags & BIND_GEOMETRY) + m_d3dDeviceContext.GSSetSamplers(samplerIndex, 1, &m_d3dSamplerState); + if (flags & BIND_PIXEL) + m_d3dDeviceContext.PSSetSamplers(samplerIndex, 1, &m_d3dSamplerState); + if (flags & BIND_HULL) + m_d3dDeviceContext.HSSetSamplers(samplerIndex, 1, &m_d3dSamplerState); + if (flags & BIND_DOMAIN) + m_d3dDeviceContext.DSSetSamplers(samplerIndex, 1, &m_d3dSamplerState); + } + } + else + { + ID3D11ShaderResourceView* nullResources[] = { NULL }; + m_d3dDeviceContext.VSSetShaderResources(samplerIndex, 1, nullResources); + m_d3dDeviceContext.GSSetShaderResources(samplerIndex, 1, nullResources); + m_d3dDeviceContext.PSSetShaderResources(samplerIndex, 1, nullResources); + m_d3dDeviceContext.HSSetShaderResources(samplerIndex, 1, nullResources); + m_d3dDeviceContext.DSSetShaderResources(samplerIndex, 1, nullResources); + ID3D11SamplerState* nullSamplers[] = { NULL }; + m_d3dDeviceContext.VSSetSamplers(samplerIndex, 1, nullSamplers); + m_d3dDeviceContext.GSSetSamplers(samplerIndex, 1, nullSamplers); + m_d3dDeviceContext.PSSetSamplers(samplerIndex, 1, nullSamplers); + m_d3dDeviceContext.HSSetSamplers(samplerIndex, 1, nullSamplers); + m_d3dDeviceContext.DSSetSamplers(samplerIndex, 1, nullSamplers); + } +} + +void D3D11RendererTexture3D::onDeviceLost(void) +{ + dxSafeRelease(m_d3dTexture); + dxSafeRelease(m_d3dSamplerState); + dxSafeRelease(m_d3dSRV); +} + +void D3D11RendererTexture3D::onDeviceReset(void) +{ + HRESULT result = S_OK; + if (!m_d3dTexture) + { + D3D11_SUBRESOURCE_DATA* pData = isDepthStencilFormat(getFormat()) ? NULL : m_resourceData; + result = m_d3dDevice.CreateTexture3D(&m_d3dTextureDesc, pData, &m_d3dTexture); + RENDERER_ASSERT(SUCCEEDED(result), "Unable to create D3D11 Texture."); + } + if (SUCCEEDED(result) && !m_d3dSamplerState) + { + result = m_d3dDevice.CreateSamplerState(&m_d3dSamplerDesc, &m_d3dSamplerState); + RENDERER_ASSERT(SUCCEEDED(result), "Unable to create D3D11 Sampler."); + } + if (SUCCEEDED(result) && m_d3dTextureDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE && !m_d3dSRV) + { + result = m_d3dDevice.CreateShaderResourceView(m_d3dTexture, &m_d3dSRVDesc, &m_d3dSRV); + RENDERER_ASSERT(SUCCEEDED(result), "Unable to create D3D11 Shader Resource View."); + } + RENDERER_ASSERT((m_d3dTextureDesc.BindFlags & D3D11_BIND_RENDER_TARGET) == 0, "D3D11 3D Texture cannot be bound as render target."); + RENDERER_ASSERT((m_d3dTextureDesc.BindFlags & D3D11_BIND_DEPTH_STENCIL) == 0, "D3D11 3D Texture cannot be bound as depth stencil."); +} + + +void D3D11RendererTexture3D::loadTextureDesc(const RendererTexture3DDesc& desc) +{ + //memset(&m_d3dTextureDesc, 0, sizeof(m_d3dTextureDesc)); + m_d3dTextureDesc = D3D11_TEXTURE3D_DESC(); + m_d3dTextureDesc.Width = getWidth(); + m_d3dTextureDesc.Height = getHeight(); + m_d3dTextureDesc.Depth = getDepth(); + m_d3dTextureDesc.MipLevels = getNumLevels(); + m_d3dTextureDesc.Format = getD3D11TextureFormat(desc.format); + m_d3dTextureDesc.CPUAccessFlags = 0; + m_d3dTextureDesc.Usage = D3D11_USAGE_DEFAULT; + m_d3dTextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + + loadResourceDesc(desc); + + loadSamplerDesc(desc); + + { + m_data = new PxU8*[getNumLevels()]; + m_resourceData = new D3D11_SUBRESOURCE_DATA[getNumLevels()]; + memset(m_data, 0, sizeof(PxU8)*getNumLevels()); + memset(m_resourceData, 0, sizeof(D3D11_SUBRESOURCE_DATA)*getNumLevels()); + + for (PxU32 i = 0; i < desc.numLevels; i++) + { + PxU32 w = getLevelDimension(getWidth(), i); + PxU32 h = getLevelDimension(getHeight(), i); + PxU32 d = getLevelDimension(getDepth(), i); + PxU32 levelSize = computeImageByteSize(w, h, d, desc.format); + m_data[i] = new PxU8[levelSize]; + memset(m_data[i], 0, levelSize); + m_resourceData[i].pSysMem = m_data[i]; + m_resourceData[i].SysMemPitch = levelSize / d / h; + m_resourceData[i].SysMemSlicePitch = levelSize / d; + } + } +} + +void D3D11RendererTexture3D::loadSamplerDesc(const RendererTexture3DDesc& desc) +{ + m_d3dSamplerDesc.Filter = getD3D11TextureFilter(desc.filter); + m_d3dSamplerDesc.AddressU = getD3D11TextureAddressing(desc.addressingU); + m_d3dSamplerDesc.AddressV = getD3D11TextureAddressing(desc.addressingV); + m_d3dSamplerDesc.AddressW = getD3D11TextureAddressing(desc.addressingW); + m_d3dSamplerDesc.MipLODBias = 0.f; + m_d3dSamplerDesc.MaxAnisotropy = 1; + m_d3dSamplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + m_d3dSamplerDesc.BorderColor[0] = m_d3dSamplerDesc.BorderColor[1] = m_d3dSamplerDesc.BorderColor[2] = m_d3dSamplerDesc.BorderColor[3] = 0.; + m_d3dSamplerDesc.MinLOD = 0; + if (desc.numLevels <= 1) + { + m_d3dSamplerDesc.MaxLOD = 0.; + } + else + { + m_d3dSamplerDesc.MaxLOD = D3D11_FLOAT32_MAX; + } +} + +void D3D11RendererTexture3D::loadResourceDesc(const RendererTexture3DDesc& desc) +{ + m_d3dSRVDesc.Format = (m_d3dTextureDesc.Format == DXGI_FORMAT_R16_TYPELESS) ? DXGI_FORMAT_R16_UNORM : m_d3dTextureDesc.Format; + m_d3dSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + m_d3dSRVDesc.Texture3D.MipLevels = m_d3dTextureDesc.MipLevels; + m_d3dSRVDesc.Texture3D.MostDetailedMip = 0; +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTexture3D.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTexture3D.h new file mode 100644 index 00000000..fa19382a --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTexture3D.h @@ -0,0 +1,88 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D11_RENDERER_TEXTURE_3D_H +#define D3D11_RENDERER_TEXTURE_3D_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include <RendererTexture.h> + +#include "D3D11Renderer.h" +#include "D3D11RendererTextureCommon.h" + +namespace SampleRenderer +{ + +class D3D11RendererTexture3D : public RendererTexture3D, public D3D11RendererResource +{ + friend class D3D11RendererTarget; + friend class D3D11RendererSpotLight; +public: + D3D11RendererTexture3D(ID3D11Device& d3dDevice, ID3D11DeviceContext& d3dDeviceContext, const RendererTexture3DDesc& desc); + virtual ~D3D11RendererTexture3D(void); + +public: + virtual void* lockLevel(PxU32 level, PxU32& pitch); + virtual void unlockLevel(PxU32 level); + + void bind(PxU32 samplerIndex, PxU32 flags = BIND_PIXEL); + + virtual void select(PxU32 stageIndex) + { + bind(stageIndex); + } + +private: + virtual void onDeviceLost(void); + virtual void onDeviceReset(void); + + void loadTextureDesc(const RendererTexture3DDesc&); + void loadSamplerDesc(const RendererTexture3DDesc&); + void loadResourceDesc(const RendererTexture3DDesc&); + +private: + ID3D11Device& m_d3dDevice; + ID3D11DeviceContext& m_d3dDeviceContext; + ID3D11Texture3D* m_d3dTexture; + D3D11_TEXTURE3D_DESC m_d3dTextureDesc; + + ID3D11SamplerState* m_d3dSamplerState; + D3D11_SAMPLER_DESC m_d3dSamplerDesc; + + ID3D11ShaderResourceView* m_d3dSRV; + D3D11_SHADER_RESOURCE_VIEW_DESC m_d3dSRVDesc; + + PxU8** m_data; + D3D11_SUBRESOURCE_DATA* m_resourceData; +}; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTextureCommon.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTextureCommon.h new file mode 100644 index 00000000..3d3321d0 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTextureCommon.h @@ -0,0 +1,107 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D11_RENDERER_TEXTURE_COMMON_H +#define D3D11_RENDERER_TEXTURE_COMMON_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include <RendererTexture.h> +#include <RendererTextureDesc.h> +#include <SamplePlatform.h> + +#include "D3D11RendererTraits.h" + + +namespace SampleRenderer +{ + +enum TEXTURE_BIND_FLAGS +{ + BIND_NONE = 0, + BIND_VERTEX = 1 << D3DTypes::SHADER_VERTEX, + BIND_GEOMETRY = 1 << D3DTypes::SHADER_GEOMETRY, + BIND_PIXEL = 1 << D3DTypes::SHADER_PIXEL, + BIND_HULL = 1 << D3DTypes::SHADER_HULL, + BIND_DOMAIN = 1 << D3DTypes::SHADER_DOMAIN, + BIND_ALL = (1 << D3DTypes::NUM_SHADER_TYPES) - 1 +}; + +PX_INLINE PxU32 getBindFlags(D3DType d3dType) { return 1 << d3dType; } + +PX_INLINE DXGI_FORMAT getD3D11TextureFormat(RendererTexture::Format format) +{ + DXGI_FORMAT dxgiFormat = static_cast<DXGI_FORMAT>(SampleFramework::SamplePlatform::platform()->getD3D11TextureFormat(format)); + RENDERER_ASSERT(dxgiFormat != DXGI_FORMAT_UNKNOWN, "Unable to convert to D3D11 Texture Format."); + return dxgiFormat; +} + +PX_INLINE D3D11_FILTER getD3D11TextureFilter(RendererTexture::Filter filter) +{ + D3D11_FILTER d3dFilter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + switch (filter) + { + case RendererTexture2D::FILTER_NEAREST: + d3dFilter = D3D11_FILTER_MIN_MAG_MIP_POINT; + break; + case RendererTexture2D::FILTER_LINEAR: + d3dFilter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + break; + case RendererTexture2D::FILTER_ANISOTROPIC: + d3dFilter = D3D11_FILTER_ANISOTROPIC; + break; + default: + RENDERER_ASSERT(0, "Unable to convert to D3D11 Filter mode."); + } + return d3dFilter; +} + +PX_INLINE D3D11_TEXTURE_ADDRESS_MODE getD3D11TextureAddressing(RendererTexture2D::Addressing addressing) +{ + D3D11_TEXTURE_ADDRESS_MODE d3dAddressing = (D3D11_TEXTURE_ADDRESS_MODE)0; + switch (addressing) + { + case RendererTexture2D::ADDRESSING_WRAP: + d3dAddressing = D3D11_TEXTURE_ADDRESS_WRAP; + break; + case RendererTexture2D::ADDRESSING_CLAMP: + d3dAddressing = D3D11_TEXTURE_ADDRESS_CLAMP; + break; + case RendererTexture2D::ADDRESSING_MIRROR: + d3dAddressing = D3D11_TEXTURE_ADDRESS_MIRROR; + break; + } + RENDERER_ASSERT(d3dAddressing != 0, "Unable to convert to D3D11 Addressing mode."); + return d3dAddressing; +} + +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) + +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTraits.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTraits.h new file mode 100644 index 00000000..ca8cd29f --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererTraits.h @@ -0,0 +1,317 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D11_RENDERER_TRAITS_H +#define D3D11_RENDERER_TRAITS_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include <tuple> + +namespace SampleRenderer +{ + +namespace D3DTypes +{ + enum D3DType + { + SHADER_PIXEL = 0, + SHADER_VERTEX, + SHADER_GEOMETRY, + SHADER_HULL, + SHADER_DOMAIN, + LAYOUT_INPUT, + STATE_RASTERIZER, + STATE_BLEND, + STATE_DEPTHSTENCIL, + NUM_TYPES, + NUM_SHADER_TYPES = SHADER_DOMAIN + 1, + NUM_NON_PIXEL_SHADER_TYPES = NUM_SHADER_TYPES - 1, + INVALID = NUM_TYPES + }; +} +typedef D3DTypes::D3DType D3DType; + +typedef std::string D3DStringKey; + +template<typename d3d_type> +class D3DTraits +{ +public: + typedef D3DStringKey key_type; + typedef IUnknown* value_type; + static D3DType getType() { return D3DTypes::INVALID; } +}; + +template <> +class D3DTraits<ID3D11VertexShader> +{ +public: + // InputLayoutHash + Shader Name + typedef std::pair<PxU64, D3DStringKey> key_type; + typedef std::pair<ID3D11VertexShader*, ID3DBlob*> value_type; + static const char* getEntry() { return "vmain"; } + static const char* getProfile(D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0) + { + switch(featureLevel) + { +#if PX_XBOXONE + case D3D_FEATURE_LEVEL_11_1: return "vs_5_0"; +#endif + case D3D_FEATURE_LEVEL_11_0: return "vs_5_0"; + case D3D_FEATURE_LEVEL_10_1: return "vs_4_1"; + case D3D_FEATURE_LEVEL_10_0: return "vs_4_0"; + case D3D_FEATURE_LEVEL_9_1: return "vs_4_0_level_9_1"; + case D3D_FEATURE_LEVEL_9_2: return "vs_4_0_level_9_2"; + case D3D_FEATURE_LEVEL_9_3: return "vs_4_0_level_9_3"; + default: RENDERER_ASSERT(0, "Invalid feature level"); return "vs_invalid"; + } + }; + static D3DType getType() { return D3DTypes::SHADER_VERTEX; } + static HRESULT create( ID3D11Device* pDevice, const void *pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage *pClassLinkage, ID3D11VertexShader **ppShader) + { + return pDevice->CreateVertexShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppShader); + } + static void setConstants( ID3D11DeviceContext* pContext, UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers ) + { + pContext->VSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + } +}; + +template <> +class D3DTraits<ID3D11PixelShader> +{ +public: + // Pass + Shader Name + typedef std::pair<PxU32, D3DStringKey> key_type; + typedef std::pair<ID3D11PixelShader*, ID3DBlob*> value_type; + static const char* getEntry() { return "fmain"; } + static const char* getProfile(D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0) { + switch(featureLevel) + { +#if PX_XBOXONE + case D3D_FEATURE_LEVEL_11_1: return "ps_5_0"; +#endif + case D3D_FEATURE_LEVEL_11_0: return "ps_5_0"; + case D3D_FEATURE_LEVEL_10_1: return "ps_4_1"; + case D3D_FEATURE_LEVEL_10_0: return "ps_4_0"; + case D3D_FEATURE_LEVEL_9_1: return "ps_4_0_level_9_1"; + case D3D_FEATURE_LEVEL_9_2: return "ps_4_0_level_9_2"; + case D3D_FEATURE_LEVEL_9_3: return "ps_4_0_level_9_3"; + default: RENDERER_ASSERT(0, "Invalid feature level"); return "ps_invalid"; + }; + } + static D3DType getType() { return D3DTypes::SHADER_PIXEL; } + static HRESULT create( ID3D11Device* pDevice, const void *pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage *pClassLinkage, ID3D11PixelShader **ppShader) + { + return pDevice->CreatePixelShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppShader); + } + static void setConstants( ID3D11DeviceContext* pContext, UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers ) + { + pContext->PSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + } +}; + +template <> +class D3DTraits<ID3D11GeometryShader> +{ +public: + // Shader Name + typedef D3DStringKey key_type; + typedef std::pair<ID3D11GeometryShader*,ID3DBlob*> value_type; + static const char* getEntry() { return "gmain"; } + static const char* getProfile(D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0) + { + switch(featureLevel) + { +#if PX_XBOXONE + case D3D_FEATURE_LEVEL_11_1: return "gs_5_0"; +#endif + case D3D_FEATURE_LEVEL_11_0: return "gs_5_0"; + case D3D_FEATURE_LEVEL_10_1: return "gs_4_1"; + case D3D_FEATURE_LEVEL_10_0: return "gs_4_0"; + default: RENDERER_ASSERT(0, "Invalid geometry shader feature level") return "gs_invalid"; + }; + } + + static D3DType getType() { return D3DTypes::SHADER_GEOMETRY; } + static HRESULT create( ID3D11Device* pDevice, const void *pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage *pClassLinkage, ID3D11GeometryShader **ppShader) + { + return pDevice->CreateGeometryShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppShader); + } + static void setConstants( ID3D11DeviceContext* pContext, UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers ) + { + pContext->GSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + } +}; + +template <> +class D3DTraits<ID3D11HullShader> +{ +public: + // Shader Name + typedef std::pair<PxU32, D3DStringKey> key_type; + typedef std::pair<ID3D11HullShader*,ID3DBlob*> value_type; + static const char* getEntry() { return "hmain"; } + static const char* getProfile(D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0) + { + switch(featureLevel) + { +#if PX_XBOXONE + case D3D_FEATURE_LEVEL_11_1: return "hs_5_0"; +#endif + case D3D_FEATURE_LEVEL_11_0: return "hs_5_0"; + default: RENDERER_ASSERT(0, "Invalid hull shader feature level") return "hs_invalid"; + }; + } + static D3DType getType() { return D3DTypes::SHADER_HULL; } + static HRESULT create( ID3D11Device* pDevice, const void *pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage *pClassLinkage, ID3D11HullShader **ppShader) + { + return pDevice->CreateHullShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppShader); + } + static void setConstants( ID3D11DeviceContext* pContext, UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers ) + { + pContext->HSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + } +}; + +template <> +class D3DTraits<ID3D11DomainShader> +{ +public: + // Shader Name + typedef std::pair<PxU32, D3DStringKey> key_type; + typedef std::pair<ID3D11DomainShader*, ID3DBlob*> value_type; + static const char* getEntry() { return "dmain"; } + static const char* getProfile(D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0) + { + switch(featureLevel) + { +#if PX_XBOXONE + case D3D_FEATURE_LEVEL_11_1: return "ds_5_0"; +#endif + case D3D_FEATURE_LEVEL_11_0: return "ds_5_0"; + default: RENDERER_ASSERT(0, "Invalid domain shader feature level") return "ds_invalid"; + }; + } + static D3DType getType() { return D3DTypes::SHADER_DOMAIN; } + static HRESULT create( ID3D11Device* pDevice, const void *pShaderBytecode, SIZE_T BytecodeLength, ID3D11ClassLinkage *pClassLinkage, ID3D11DomainShader **ppShader) + { + return pDevice->CreateDomainShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppShader); + } + static void setConstants( ID3D11DeviceContext* pContext, UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers ) + { + pContext->DSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + } +}; + +template <> +class D3DTraits<ID3D11InputLayout> +{ +public: + // InputLayoutHash + Shader Name + typedef std::pair<PxU64, ID3DBlob*> key_type; + typedef ID3D11InputLayout* value_type; + static D3DType getType() { return D3DTypes::LAYOUT_INPUT; } +}; + +template <> +class D3DTraits<ID3D11RasterizerState> +{ +public: + typedef std::tr1::tuple<D3D11_FILL_MODE, D3D11_CULL_MODE, int> key_type; + typedef ID3D11RasterizerState* value_type; + static D3DType getType() { return D3DTypes::STATE_RASTERIZER; } +}; + + +template <> +class D3DTraits<ID3D11DepthStencilState> +{ +public: + // Depth enable + stencil enable + typedef std::pair<bool, bool> key_type; + typedef ID3D11DepthStencilState* value_type; + static D3DType getType() { return D3DTypes::STATE_DEPTHSTENCIL; } +}; + + +template <> +class D3DTraits<ID3D11BlendState> +{ +public: + typedef D3D11_RENDER_TARGET_BLEND_DESC key_type; + typedef ID3D11BlendState* value_type; + static D3DType getType() { return D3DTypes::STATE_BLEND; } +}; + +// This lets us lookup a traits class based on the D3DType key, which is rather handy +template<PxU32 N> +class D3DTraitsLookup { }; +template<> +class D3DTraitsLookup<D3DTypes::SHADER_PIXEL> { typedef ID3D11PixelShader d3d_type; }; +template<> +class D3DTraitsLookup<D3DTypes::SHADER_VERTEX> { typedef ID3D11VertexShader d3d_type; }; +template<> +class D3DTraitsLookup<D3DTypes::SHADER_GEOMETRY> { typedef ID3D11GeometryShader d3d_type; }; +template<> +class D3DTraitsLookup<D3DTypes::SHADER_HULL> { typedef ID3D11HullShader d3d_type; }; +template<> +class D3DTraitsLookup<D3DTypes::SHADER_DOMAIN> { typedef ID3D11DomainShader d3d_type; }; +template<> +class D3DTraitsLookup<D3DTypes::LAYOUT_INPUT> { typedef ID3D11InputLayout d3d_type; }; +template<> +class D3DTraitsLookup<D3DTypes::STATE_BLEND> { typedef ID3D11BlendState d3d_type; }; +template<> +class D3DTraitsLookup<D3DTypes::STATE_DEPTHSTENCIL> { typedef ID3D11DepthStencilState d3d_type; }; +template<> +class D3DTraitsLookup<D3DTypes::STATE_RASTERIZER> { typedef ID3D11RasterizerState d3d_type; }; + +template <typename T> +struct NullTraits +{ + static T get() { return 0; } +}; + +template <typename T> +struct NullTraits<T*> +{ + static T* get() { return NULL; } +}; + +template<typename T1,typename T2> +struct NullTraits< std::pair<T1*,T2*> > +{ + static std::pair<T1*,T2*> get() { return std::pair<T1*,T2*>((T1*)NULL,(T2*)NULL); } +}; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) + +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererUtils.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererUtils.cpp new file mode 100644 index 00000000..3113ba50 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererUtils.cpp @@ -0,0 +1,502 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include "D3D11RendererUtils.h" +#include "D3D11RendererMemoryMacros.h" + +#if !PX_XBOXONE +#include "D3DX11.h" +#endif +#include "D3Dcompiler.h" + +// for PsString.h +#include <PsString.h> +#include <PxTkFile.h> + +using namespace SampleRenderer; +namespace Ps = physx::shdfnd; + + +/****************************************** +* D3DX11::D3DX11 * +*******************************************/ + +D3DX11::D3DX11(void) + : m_pD3DX11CompileFromFile(NULL), + m_pD3DX11CompileFromMemory(NULL), + m_pD3DReflect(NULL) +{ +#if defined(RENDERER_WINDOWS) && !PX_XBOXONE + m_library = LoadLibraryA(D3DX11_DLL); + if (!m_library) + { + // This version should be present on all valid DX11 machines + m_library = LoadLibraryA("d3dx11_42.dll"); + if (!m_library) + { + MessageBoxA(0, "Unable to load " D3DX11_DLL ". Please install the latest DirectX End User Runtime available at www.microsoft.com/directx.", "Renderer Error.", MB_OK); + } + } + if (m_library) + { + m_pD3DX11CompileFromFile = (D3DX11COMPILEFROMFILE)GetProcAddress(m_library, "D3DX11CompileFromFileA"); + RENDERER_ASSERT(m_pD3DX11CompileFromFile, "Unable to find D3DX11 Function D3DX11CompileFromFile in " D3DX11_DLL "."); + m_pD3DX11CompileFromMemory = (D3DX11COMPILEFROMMEMORY)GetProcAddress(m_library, "D3DX11CompileFromMemory"); + RENDERER_ASSERT(m_pD3DX11CompileFromMemory, "Unable to find D3DX11 Function D3DX11CompileFromFile in " D3DX11_DLL "."); + m_pD3DX11SaveTextureToMemory = (D3DX11SAVETEXTURETOMEMORY)GetProcAddress(m_library, "D3DX11SaveTextureToMemory"); + RENDERER_ASSERT(m_pD3DX11SaveTextureToMemory, "Unable to find D3DX11 Function D3DX11SaveTextureToMemory in " D3DX11_DLL "."); + } + + m_compiler_library = LoadLibraryA(D3DCOMPILER_DLL); + if (!m_compiler_library) + { + // This version should be present on all valid DX11 machines + m_library = LoadLibraryA("D3DCompiler_42.dll"); + if (!m_compiler_library) + { + MessageBoxA(0, "Unable to load " D3DCOMPILER_DLL ". Please install the latest DirectX End User Runtime available at www.microsoft.com/directx.", "Renderer Error.", MB_OK); + } + } + if (m_compiler_library) + { + m_pD3DReflect = (D3DREFLECT)GetProcAddress(m_compiler_library, "D3DReflect"); + RENDERER_ASSERT(m_pD3DReflect, "Unable to find D3D Function D3DReflect in " D3DCOMPILER_DLL "."); + m_pD3DCreateBlob = (D3DCREATEBLOB)GetProcAddress(m_compiler_library, "D3DCreateBlob"); + RENDERER_ASSERT(m_pD3DCreateBlob, "Unable to find D3D Function D3DCreateBlob in " D3DCOMPILER_DLL "."); + } +#endif +} + +D3DX11::~D3DX11(void) +{ +#if defined(RENDERER_WINDOWS) + if (m_library) + { + FreeLibrary(m_library); + m_library = 0; + } + if (m_compiler_library) + { + FreeLibrary(m_compiler_library); + m_compiler_library = 0; + } +#endif +} + +HRESULT D3DX11::compileShaderFromFile(LPCSTR pSrcFile, + CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + UINT Flags1, + UINT Flags2, + ID3DX11ThreadPump* pPump, + ID3D10Blob** ppShader, + ID3D10Blob** ppErrorMsgs, + HRESULT* pHResult) const +{ +#if !PX_XBOXONE + return m_pD3DX11CompileFromFile(pSrcFile, + pDefines, + pInclude, + pFunctionName, + pProfile, + Flags1, + Flags2, + pPump, + ppShader, + ppErrorMsgs, + pHResult); +#else + const size_t bufferSize = 256; + wchar_t wSrcFile[bufferSize]; + size_t length = 0; + mbstowcs_s(&length, wSrcFile, strlen(pSrcFile) + 1, pSrcFile, bufferSize); + HRESULT result = D3DCompileFromFile(wSrcFile, pDefines, pInclude, pFunctionName, pProfile, Flags1, Flags2, ppShader, ppErrorMsgs); + if(pHResult) + *pHResult = result; + return result; +#endif +} + +HRESULT D3DX11::compileShaderFromMemory(LPCSTR pSrcData, + SIZE_T SrcDataLen, + LPCSTR pFileName, + CONST D3D10_SHADER_MACRO* pDefines, + LPD3D10INCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + UINT Flags1, + UINT Flags2, + ID3DX11ThreadPump* pPump, + ID3D10Blob** ppShader, + ID3D10Blob** ppErrorMsgs, + HRESULT* pHResult) const +{ +#if !PX_XBOXONE + return m_pD3DX11CompileFromMemory(pSrcData, + SrcDataLen, + pFileName, + pDefines, + pInclude, + pFunctionName, + pProfile, + Flags1, + Flags2, + pPump, + ppShader, + ppErrorMsgs, + pHResult); +#else + HRESULT result = D3DCompile(pSrcData, SrcDataLen, pFileName, pDefines, pInclude, pFunctionName, pProfile, Flags1, Flags2, ppShader, ppErrorMsgs); + if(pHResult) + *pHResult = result; + return result; +#endif +} + +HRESULT D3DX11::reflect(LPCVOID pSrcData, SIZE_T SrcDataSize, REFIID pInterface, void** ppReflector) +{ +#if !PX_XBOXONE + return m_pD3DReflect(pSrcData, SrcDataSize, pInterface, ppReflector); +#else + return D3DReflect(pSrcData, SrcDataSize, pInterface, ppReflector); +#endif +} + +HRESULT D3DX11::saveTextureToMemory( ID3D11DeviceContext *pContext, ID3D11Resource *pSrcTexture, D3DX11_IMAGE_FILE_FORMAT DestFormat, LPD3D10BLOB *ppDestBuf, UINT Flags ) +{ + return m_pD3DX11SaveTextureToMemory(pContext, pSrcTexture, DestFormat, ppDestBuf, Flags); +} + +HRESULT D3DX11::createBlob(SIZE_T Size, ID3DBlob **ppBlob) +{ + return m_pD3DCreateBlob(Size, ppBlob); +} + +void D3DX11::processCompileErrors(ID3DBlob* errors) +{ +#if defined(RENDERER_WINDOWS) && !PX_XBOXONE + if (errors) + { + const char* errorStr = (const char*)errors->GetBufferPointer(); + if (errorStr) + { + static bool ignoreErrors = false; + if (!ignoreErrors) + { + int ret = MessageBoxA(0, errorStr, "D3DXCompileShaderFromFile Error", MB_ABORTRETRYIGNORE); + if (ret == IDABORT) + { + exit(0); + } + else if (ret == IDIGNORE) + { + ignoreErrors = true; + } + } + } + } +#endif +} + +PxU64 D3DX11::getInputHash(const std::vector<D3D11_INPUT_ELEMENT_DESC>& inputDesc) +{ + return getInputHash(&inputDesc[0], (UINT)inputDesc.size()); +} + +static PxU8 sizeOfFormatElement(DXGI_FORMAT format) +{ + switch( format ) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + return 128; + + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + return 96; + + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + return 64; + + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + return 32; + + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: + return 16; + + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: + return 8; + + // Compressed format; http://msdn2.microso.../bb694531(VS.85).aspx + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + return 128; + + // Compressed format; http://msdn2.microso.../bb694531(VS.85).aspx + case DXGI_FORMAT_R1_UNORM: + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + return 64; + + // Compressed format; http://msdn2.microso.../bb694531(VS.85).aspx + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + return 32; + + // These are compressed, but bit-size information is unclear. + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + return 32; + + case DXGI_FORMAT_UNKNOWN: + default: + return 0; + } +} + +PxU64 D3DX11::getInputHash(const D3D11_INPUT_ELEMENT_DESC* inputDesc, UINT numInputDescs) +{ + enum ShaderInputFlag + { + USE_NONE = 0x00, + USE_POSITION = 0x01, + USE_NORMAL = USE_POSITION << 1, + USE_TANGENT = USE_POSITION << 2, + USE_COLOR = USE_POSITION << 3, + USE_TEXCOORD = USE_POSITION << 4, + NUM_INPUT_TYPES = 5, + }; + + // Each input element gets a certain number of bits in the hash + const PxU8 bitsPerElement = physx::PxMax((PxU8)((sizeof(PxU64) * 8) / numInputDescs), (PxU8)1); + + // Restrict the maximum amount each set of element bits can be shifted + const PxU8 maxSizeShift = physx::PxMin(bitsPerElement, (PxU8)NUM_INPUT_TYPES); + + PxU64 inputHash = 0; + for (UINT i = 0; i < numInputDescs; ++i) + { + if(inputDesc->SemanticName) + { + PxU8 flag = USE_NONE; + + if (Ps::stricmp(inputDesc[i].SemanticName, "TEXCOORD") == 0) + { + flag = USE_TEXCOORD; + } + else if (Ps::stricmp(inputDesc[i].SemanticName, "NORMAL") == 0) + { + flag = USE_NORMAL; + } + else if (Ps::stricmp(inputDesc[i].SemanticName, "TANGENT") == 0) + { + flag = USE_TANGENT; + } + else if (Ps::stricmp(inputDesc[i].SemanticName, "COLOR") == 0) + { + flag = USE_COLOR; + } + else if (Ps::stricmp(inputDesc[i].SemanticName, "POSITION") == 0) + { + flag = USE_POSITION; + } + + static const PxU8 bitsPerDefaultFormat = sizeOfFormatElement(DXGI_FORMAT_R8G8B8A8_UINT); + PX_ASSERT(bitsPerDefaultFormat > 0); + + // Shift the semantic bit depending on the element's relative format size + const PxU8 elementSizeShift = (sizeOfFormatElement(inputDesc[i].Format) / bitsPerDefaultFormat) & maxSizeShift; + + // Shift the semantic bit depending on it's order in the element array + const PxU8 elementOrderShift = (PxU8)(i * bitsPerElement); + + // Add the element's bits to the hash, shifted by it's order in the element array + inputHash |= (flag << (elementSizeShift + elementOrderShift)); + } + } + + return inputHash; +} + + +/******************************************* +* D3D11ShaderIncluder::D3D11ShaderIncluder * +*******************************************/ + +D3D11ShaderIncluder::D3D11ShaderIncluder(const char* assetDir) : m_assetDir(assetDir) {} + +HRESULT D3D11ShaderIncluder::Open( + D3D_INCLUDE_TYPE includeType, + LPCSTR fileName, + LPCVOID parentData, + LPCVOID* data, + UINT* dataSize +) +{ + HRESULT result = D3D11_ERROR_FILE_NOT_FOUND; + + char fullpath[1024]; + Ps::strlcpy(fullpath, 1024, m_assetDir); + Ps::strlcat(fullpath, 1024, "shaders/"); + if (includeType == D3D10_INCLUDE_SYSTEM) + { + Ps::strlcat(fullpath, 1024, "include/"); + } + Ps::strlcat(fullpath, 1024, fileName); + + FILE* file = 0; + PxToolkit::fopen_s(&file, fullpath, "r"); + if (file) + { + fseek(file, 0, SEEK_END); + size_t fileLen = ftell(file); + if (fileLen > 1) + { + fseek(file, 0, SEEK_SET); + char* fileData = new char[fileLen + 1]; + fileLen = fread(fileData, 1, fileLen, file); + fileData[fileLen] = 0; + *data = fileData; + *dataSize = (UINT)fileLen; + } + fclose(file); + result = S_OK; + } + RENDERER_ASSERT(result == S_OK, "Failed to include shader header."); + return result; +} + +HRESULT D3D11ShaderIncluder::Close(LPCVOID data) +{ + delete []((char*)data); + return S_OK; +} + +/*************************************** +* D3D11ShaderCacher::D3D11ShaderCacher * +***************************************/ + +D3D11ShaderCacher::D3D11ShaderCacher(D3D11RendererResourceManager* pResourceManager) +: mResourceManager(pResourceManager) +{ + RENDERER_ASSERT(pResourceManager, "Invalid D3D resource manager"); +} + + +/*************************************** +* D3D11ShaderLoader::D3D11ShaderLoader * +***************************************/ + +D3D11ShaderLoader::D3D11ShaderLoader(D3D11Renderer& renderer) + : mFeatureLevel(renderer.getFeatureLevel()), + mCacher(renderer.getResourceManager()), + mCompiler(renderer.getD3DX11()), + mIncluder(renderer.getAssetDir()), + mDevice(renderer.getD3DDevice()) +{ + RENDERER_ASSERT(mCompiler, "Invalid D3D compiler"); + RENDERER_ASSERT(mDevice, "Invalid D3D device"); +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererUtils.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererUtils.h new file mode 100644 index 00000000..86d42ddc --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererUtils.h @@ -0,0 +1,296 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#ifndef D3D11_RENDERER_UTILS_H +#define D3D11_RENDERER_UTILS_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include "D3D11Renderer.h" +#include "D3D11RendererTraits.h" + +#if !PX_XBOXONE +#include <d3dx11tex.h> +#else +#define D3D10_SHADER_MACRO D3D_SHADER_MACRO +#define LPD3D10INCLUDE LPD3DINCLUDE +#define D3DX11_IMAGE_FILE_FORMAT int +#endif + +struct ID3DX11ThreadPump; + +namespace SampleRenderer +{ + +PX_INLINE PxU32 fast_hash(const char *str, SIZE_T wrdlen) +{ + // "FNV" string hash + const PxU32 PRIME = 1607; + + PxU32 hash32 = 2166136261; + const char *p = str; + + for(; wrdlen >= sizeof(PxU32); wrdlen -= sizeof(PxU32), p += sizeof(PxU32)) { + hash32 = (hash32 ^ *(PxU32 *)p) * PRIME; + } + if (wrdlen & sizeof(PxU16)) { + hash32 = (hash32 ^ *(PxU16*)p) * PRIME; + p += sizeof(PxU16); + } + if (wrdlen & 1) + hash32 = (hash32 ^ *p) * PRIME; + + return hash32 ^ (hash32 >> 16); +} + +class D3D11StringKey +{ +public: + D3D11StringKey(const char* stringKey) : mStringHash(fast_hash(stringKey, strlen(stringKey))) { } + D3D11StringKey(const std::string& stringKey) : mStringHash(fast_hash(stringKey.c_str(), stringKey.length())) { } + bool operator<(const D3D11StringKey& other) const { return mStringHash < other.mStringHash; } +private: + D3D11StringKey(); + PxU32 mStringHash; +}; + +class D3DX11 +{ + friend class D3D11Renderer; +private: + D3DX11(void); + ~D3DX11(void); + +public: + HRESULT compileShaderFromFile(LPCSTR pSrcFile, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult) const; + HRESULT compileShaderFromMemory(LPCSTR pSrcData, SIZE_T SrcDataLen, LPCSTR pFileName, CONST D3D10_SHADER_MACRO* pDefines, LPD3D10INCLUDE pInclude, + LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump* pPump, ID3D10Blob** ppShader, ID3D10Blob** ppErrorMsgs, HRESULT* pHResult) const; + HRESULT reflect(LPCVOID pSrcData, SIZE_T SrcDataSize, REFIID pInterface, void** ppReflector); + HRESULT saveTextureToMemory(ID3D11DeviceContext *pContext, ID3D11Resource *pSrcTexture, D3DX11_IMAGE_FILE_FORMAT DestFormat, LPD3D10BLOB *ppDestBuf, UINT Flags); + HRESULT createBlob(SIZE_T Size, ID3DBlob **ppBlob); + +public: + static void processCompileErrors(ID3DBlob* errors); + + static PxU64 getInputHash(const std::vector<D3D11_INPUT_ELEMENT_DESC>& inputElementDesc); + static PxU64 getInputHash(const D3D11_INPUT_ELEMENT_DESC* inputElementDesc, UINT numInputElementDescs); + +private: +#if defined(RENDERER_WINDOWS) + HMODULE m_library; + HMODULE m_compiler_library; + + typedef HRESULT(WINAPI* D3DX11COMPILEFROMFILE)(LPCSTR, CONST D3D10_SHADER_MACRO*, LPD3D10INCLUDE, LPCSTR, LPCSTR, UINT, UINT, ID3DX11ThreadPump*, ID3D10Blob**, ID3D10Blob**, HRESULT*); + D3DX11COMPILEFROMFILE m_pD3DX11CompileFromFile; + typedef HRESULT(WINAPI* D3DX11COMPILEFROMMEMORY)(LPCSTR, SIZE_T, LPCSTR, CONST D3D10_SHADER_MACRO*, LPD3D10INCLUDE, LPCSTR, LPCSTR, UINT, UINT, ID3DX11ThreadPump*, ID3D10Blob**, ID3D10Blob**, HRESULT*); + D3DX11COMPILEFROMMEMORY m_pD3DX11CompileFromMemory; + typedef HRESULT(WINAPI* D3DREFLECT)(LPCVOID, SIZE_T, REFIID, void**); + D3DREFLECT m_pD3DReflect; + typedef HRESULT(WINAPI* D3DX11SAVETEXTURETOMEMORY)(ID3D11DeviceContext *, ID3D11Resource *, D3DX11_IMAGE_FILE_FORMAT, LPD3D10BLOB *, UINT); + D3DX11SAVETEXTURETOMEMORY m_pD3DX11SaveTextureToMemory; + typedef HRESULT(WINAPI* D3DCREATEBLOB)(SIZE_T, ID3DBlob**); + D3DCREATEBLOB m_pD3DCreateBlob; + +#endif + +}; + +class D3D11ShaderIncluder : public ID3DInclude +{ +public: + D3D11ShaderIncluder(const char* assetDir); + +private: + STDMETHOD(Open( + D3D_INCLUDE_TYPE includeType, + LPCSTR fileName, + LPCVOID parentData, + LPCVOID* data, + UINT* dataSize + )); + + STDMETHOD(Close(LPCVOID data)); + + const char* m_assetDir; +}; + + +class D3D11ShaderCacher +{ +public: + D3D11ShaderCacher(D3D11RendererResourceManager* pResourceManager); + + template<typename d3d_type> + bool check(const typename D3DTraits<d3d_type>::key_type& key, + d3d_type*& d3dResource, + ID3DBlob*& d3dResourceBlob) const + { + typename D3DTraits<d3d_type>::value_type value = mResourceManager->hasResource<d3d_type>(key); + d3dResource = value.first; + d3dResourceBlob = value.second; + return !((NULL == d3dResource) || (NULL == d3dResourceBlob)); + } + + template<typename d3d_type> + void cache(const typename D3DTraits<d3d_type>::key_type& key, + const typename D3DTraits<d3d_type>::value_type& value) + { + mResourceManager->registerResource<d3d_type>(key, value); + } + +private: + D3D11ShaderCacher(); + + D3D11RendererResourceManager* mResourceManager; +}; + +static void PxConvertToWchar(const char* inString, WCHAR* outString, int outSize) +{ + // convert to unicode + int succ = MultiByteToWideChar(CP_ACP, 0, inString, -1, outString, outSize); + + // validate + if (succ < 0) + succ = 0; + if (succ < outSize) + outString[succ] = 0; + else if (outString[outSize-1]) + outString[0] = 0; +} + +class D3D11ShaderLoader +{ +public: + D3D11ShaderLoader(D3D11Renderer& renderer); + + template<typename d3d_type> + HRESULT load(typename D3DTraits<d3d_type>::key_type shaderKey, + const char *pShaderPath, + const D3D10_SHADER_MACRO* pDefines, + d3d_type **ppShader = NULL, + ID3DBlob **ppShaderBlob = NULL, + bool bCheckCacheBeforeLoading = true, + bool *pbLoadedFromCache = NULL) + { + HRESULT result = S_OK; + d3d_type* pShader = NULL; + ID3DBlob* pShaderBlob = NULL; + + if (!bCheckCacheBeforeLoading || !mCacher.check<d3d_type>(shaderKey, pShader, pShaderBlob)) + { + result = internalLoad(pShaderPath, pDefines, &pShader, &pShaderBlob); + mCacher.cache<d3d_type>(shaderKey, std::make_pair(pShader, pShaderBlob)); + if (pbLoadedFromCache) *pbLoadedFromCache = false; + } + else if (pbLoadedFromCache) + { + *pbLoadedFromCache = true; + } + + if (SUCCEEDED(result)) + { + if (ppShader) *ppShader = pShader; + if (ppShaderBlob) *ppShaderBlob = pShaderBlob; + } + else + { + RENDERER_ASSERT(0, "Error loading D3D11 shader"); + } + + return result; + } + +protected: + template<typename d3d_type> + HRESULT internalLoad(const char* pShaderName, const D3D10_SHADER_MACRO* pDefines, d3d_type** ppShader, ID3DBlob** ppBlob) + { + HRESULT result = S_OK; + ID3DBlob* pErrorsBlob = NULL; + +#ifdef PX_USE_DX11_PRECOMPILED_SHADERS + //if(pDefines[0].Name == "RENDERER_FRAGMENT") + { + WCHAR bufferWchar[512]; + PxConvertToWchar(pShaderName,bufferWchar,512); + result = D3DReadFileToBlob(bufferWchar,ppBlob); + RENDERER_ASSERT(SUCCEEDED(result) && *ppBlob, "Failed to load precompiled shader."); + + char szBuff[1024]; + sprintf(szBuff,"Precompiled shader loaded: %s \n",pShaderName); + OutputDebugStringA(szBuff); + } +#else + const DWORD shaderFlags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR; + + result = mCompiler->compileShaderFromFile( + pShaderName, + pDefines, + &mIncluder, + D3DTraits<d3d_type>::getEntry(), + D3DTraits<d3d_type>::getProfile(mFeatureLevel), + shaderFlags, + 0, + NULL, + ppBlob, + &pErrorsBlob, + NULL + ); + D3DX11::processCompileErrors(pErrorsBlob); + RENDERER_ASSERT(SUCCEEDED(result) && *ppBlob, "Failed to compile shader."); +#endif + + if (SUCCEEDED(result) && *ppBlob) + { + result = D3DTraits<d3d_type>::create(mDevice, (*ppBlob)->GetBufferPointer(), (*ppBlob)->GetBufferSize(), NULL, ppShader); + RENDERER_ASSERT(SUCCEEDED(result) && *ppShader, "Failed to load Fragment Shader."); + } + if (pErrorsBlob) + { + pErrorsBlob->Release(); + } + return result; + } + +private: + D3D11ShaderLoader(); + D3D11ShaderLoader& operator=(const D3D11ShaderLoader&); + + D3D_FEATURE_LEVEL mFeatureLevel; + D3D11ShaderCacher mCacher; + D3D11ShaderIncluder mIncluder; + D3DX11* mCompiler; + ID3D11Device* mDevice; +}; + + +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererVariableManager.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererVariableManager.cpp new file mode 100644 index 00000000..24f1664a --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererVariableManager.cpp @@ -0,0 +1,722 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include "D3D11RendererVariableManager.h" + +#include "D3D11Renderer.h" +#include "D3D11RendererTexture2D.h" +#include "D3D11RendererTexture3D.h" +#include "D3D11RendererMemoryMacros.h" +#include "D3D11RendererUtils.h" + +#include "RendererMemoryMacros.h" + +#include <stdio.h> + +using namespace SampleRenderer; +static const PxU32 getShaderTypeKey(D3DType shaderType, RendererMaterial::Pass pass = RendererMaterial::NUM_PASSES) +{ + RENDERER_ASSERT(shaderType < D3DTypes::NUM_SHADER_TYPES && + ((shaderType > 0 && pass == RendererMaterial::NUM_PASSES) || + (shaderType == 0 && pass < RendererMaterial::NUM_PASSES)), + "Invalid shader index"); + // pass = NUM_PASSES for any non-pixel shader + // shaderType = 0 for any pixel shader + // pass + shaderType = UNIQUE for any combination + return (PxU32)shaderType + (PxU32)pass; +} + +static D3DType getD3DType(PxU32 shaderTypeKey) +{ + return D3DType(shaderTypeKey < RendererMaterial::NUM_PASSES ? D3DTypes::SHADER_PIXEL : shaderTypeKey-RendererMaterial::NUM_PASSES); +} + +class D3D11RendererVariableManager::D3D11ConstantBuffer +{ +public: + D3D11ConstantBuffer(ID3D11Buffer* pBuffer = NULL, PxU8* pData = NULL, PxU32 size = 0) + : buffer(pBuffer), + data(pData), + dataSize(size), + bDirty(false), + refCount(1) + { + + } + + ~D3D11ConstantBuffer() + { + RENDERER_ASSERT(refCount == 0, "Constant buffer not released as often as it was created."); + dxSafeRelease(buffer); + DELETEARRAY(data); + } + + void addref() + { + ++refCount; + } + + void release() + { + if(0 == --refCount) + { + delete this; + } + } + + ID3D11Buffer* buffer; + PxU8* data; + PxU32 dataSize; + mutable bool bDirty; + +protected: + PxU32 refCount; +}; + +/**************************************************** +* D3D11RendererVariableManager::D3D11SharedVariable * +****************************************************/ + +class D3D11RendererVariableManager::D3D11SharedVariable : public D3D11RendererMaterial::D3D11BaseVariable +{ + friend class D3D11RendererMaterial; + friend class D3D11RendererVariableManager; +public: + D3D11SharedVariable(const char* name, RendererMaterial::VariableType type, PxU32 offset, D3D11ConstantBuffer* pBuffer) + : D3D11RendererMaterial::D3D11BaseVariable(name, type, offset), m_pBuffer(pBuffer) + { + } + D3D11SharedVariable& operator=(const D3D11SharedVariable&) + { + return *this; + } +protected: + D3D11ConstantBuffer* m_pBuffer; +}; + +/************************************************** +* D3D11RendererVariableManager::D3D11DataVariable * +**************************************************/ + +class D3D11RendererVariableManager::D3D11DataVariable : public D3D11RendererMaterial::D3D11Variable +{ + friend class D3D11RendererMaterial; + friend class D3D11RendererVariableManager; +public: + D3D11DataVariable(const char* name, RendererMaterial::VariableType type, PxU32 offset) + : D3D11Variable(name, type, offset) + { + for (int i = 0; i < NUM_SHADER_TYPES; ++i) + { + m_pData[i] = NULL; + m_pDirtyFlags[i] = NULL; + } + } + + virtual void bind(RendererMaterial::Pass pass, const void* data) + { + for (PxU32 i = getShaderTypeKey(D3DTypes::SHADER_VERTEX); i < NUM_SHADER_TYPES; ++i) + { + internalBind(i, data); + } + internalBind(pass, data); + } + +private: + + void internalBind(PxU32 typeKey, const void* data) + { + if (m_pData[typeKey]) + { + memcpy(m_pData[typeKey], data, getDataSize()); + if (m_pDirtyFlags[typeKey]) + { + *(m_pDirtyFlags[typeKey]) = true; + } + } + } + + void addHandle(D3D11RendererVariableManager::ShaderTypeKey typeKey, PxU8* pData, bool* pDirtyFlag) + { + m_pData[typeKey] = pData; + m_pDirtyFlags[typeKey] = pDirtyFlag; + } + +private: + PxU8* m_pData[NUM_SHADER_TYPES]; + bool* m_pDirtyFlags[NUM_SHADER_TYPES]; +}; + + +/***************************************************** +* D3D11RendererVariableManager::D3D11TextureVariable * +*****************************************************/ + +class D3D11RendererVariableManager::D3D11TextureVariable : public D3D11RendererMaterial::D3D11Variable +{ + friend class D3D11RendererMaterial; + friend class D3D11RendererVariableManager; +public: + D3D11TextureVariable(const char* name, RendererMaterial::VariableType type, PxU32 offset) + : D3D11Variable(name, type, offset) + { + for (int i = 0; i < NUM_SHADER_TYPES; ++i) + { + m_bufferIndex[i] = -1; + } + } + + + virtual void bind(RendererMaterial::Pass pass, const void* data) + { + data = *(void**)data; + //RENDERER_ASSERT(data, "NULL Sampler."); + if (data) + { + for (PxU32 i = getShaderTypeKey(D3DTypes::SHADER_VERTEX); i < NUM_SHADER_TYPES; ++i) + { + internalBind(i, data); + } + internalBind(pass, data); + } + } + +private: + + void internalBind(PxU32 typeKey, const void* data) + { + if (m_bufferIndex[typeKey] != -1) + { + PxU32 bindFlags = getBindFlags(getD3DType(typeKey)); + if (RendererMaterial::VARIABLE_SAMPLER2D == getType()) + static_cast<D3D11RendererTexture2D*>((RendererTexture2D*)data)->bind(m_bufferIndex[typeKey], bindFlags); + else if (RendererMaterial::VARIABLE_SAMPLER3D == getType()) + static_cast<D3D11RendererTexture3D*>((RendererTexture2D*)data)->bind(m_bufferIndex[typeKey], bindFlags); + } + } + + void addHandle(D3D11RendererVariableManager::ShaderTypeKey typeKey, int bufferIndex) + { + m_bufferIndex[typeKey] = bufferIndex; + } + +private: + int m_bufferIndex[NUM_SHADER_TYPES]; +}; + +/******************************* +* D3D11RendererVariableManager * +*******************************/ + +D3D11RendererVariableManager::D3D11RendererVariableManager(D3D11Renderer& renderer, StringSet& cbNames, BindMode bindMode) + : mRenderer(renderer), mSharedBufferNames(cbNames), mBindMode(bindMode) +{ + +} + +D3D11RendererVariableManager::~D3D11RendererVariableManager(void) +{ + while (!mVariables.empty()) + { + delete mVariables.back(), mVariables.pop_back(); + } + + for (PxU32 i = 0; i < NUM_SHADER_TYPES; ++i) + { + for (ResourceBuffersMap::iterator it = mResourceToBuffers[i].begin(); + it != mResourceToBuffers[i].end(); + ++it) + { + for(PxU32 j = 0; j < it->second.size(); ++j) + { + it->second[j]->release(); + } + } + } +} + +class D3D11RendererResourceMapper +{ +public: + D3D11RendererResourceMapper( ID3D11DeviceContext *pContext, ID3D11Resource *pResource, UINT Subresource = 0, D3D11_MAP MapType = D3D11_MAP_WRITE_DISCARD ) + : mpContext(pContext), mpResource(pResource), mSubresource(Subresource) + { + pContext->Map(pResource, Subresource, MapType, NULL, &mMappedResource); + } + + void load(const void* pSrc, size_t srcSize) + { + RENDERER_ASSERT(mMappedResource.pData, "Invalid D3D11 mapped pointer"); + memcpy(mMappedResource.pData, pSrc, srcSize); + } + + ~D3D11RendererResourceMapper() + { + mpContext->Unmap(mpResource, mSubresource); + } + +protected: + ID3D11DeviceContext* mpContext; + ID3D11Resource* mpResource; + UINT mSubresource; + D3D11_MAPPED_SUBRESOURCE mMappedResource; +}; + +class D3D11RendererVariableBinder +{ +public: + D3D11RendererVariableBinder(ID3D11DeviceContext* pContext) + : mContext(pContext) + { + RENDERER_ASSERT(pContext, "Invalid D3D11 device context"); + } + + void bind(const D3DType d3dType, + const D3D11RendererVariableManager::ConstantBuffers* buffers, + D3D11RendererVariableManager::BindMode bindMode) + { + if (buffers && buffers->size() > 0) + { + D3D11RendererVariableManager::D3DBuffers pCBs(buffers->size()); + PxU32 cbIndex = 0; + for (D3D11RendererVariableManager::CBIterator cbIt = buffers->begin(); + cbIt != buffers->end(); + ++cbIt) + { + if ((*cbIt)->bDirty) + { + if (bindMode == D3D11RendererVariableManager::BIND_MAP) + { + D3D11RendererResourceMapper mappedResource(mContext, (*cbIt)->buffer); + mappedResource.load((*cbIt)->data, (*cbIt)->dataSize); + } + else + { + mContext->UpdateSubresource((*cbIt)->buffer, 0, NULL, (*cbIt)->data, 0, 0); + } + + (*cbIt)->bDirty = false; + } + pCBs[cbIndex++] = (*cbIt)->buffer; + } + switch (d3dType) + { + case D3DTypes::SHADER_PIXEL: D3DTraits<ID3D11PixelShader>::setConstants(mContext, 0, (UINT)pCBs.size(), &pCBs[0]); + break; + case D3DTypes::SHADER_VERTEX: D3DTraits<ID3D11VertexShader>::setConstants(mContext, 0, (UINT)pCBs.size(), &pCBs[0]); + break; + case D3DTypes::SHADER_GEOMETRY: D3DTraits<ID3D11GeometryShader>::setConstants(mContext, 0, (UINT)pCBs.size(), &pCBs[0]); + break; + case D3DTypes::SHADER_HULL: D3DTraits<ID3D11HullShader>::setConstants(mContext, 0, (UINT)pCBs.size(), &pCBs[0]); + break; + case D3DTypes::SHADER_DOMAIN: D3DTraits<ID3D11DomainShader>::setConstants(mContext, 0, (UINT)pCBs.size(), &pCBs[0]); + break; + default: + RENDERER_ASSERT(0, "Invalid D3D type"); + break; + } + } + + } + +private: + D3D11RendererVariableBinder(); + ID3D11DeviceContext* mContext; +}; + +void D3D11RendererVariableManager::bind(const void* pResource, D3DType type, RendererMaterial::Pass pass) const +{ + ID3D11DeviceContext* d3dDeviceContext = mRenderer.getD3DDeviceContext(); + ShaderTypeKey typeKey = getShaderTypeKey(type, pass); + + if (pResource && d3dDeviceContext && typeKey < NUM_SHADER_TYPES) + { + ResourceBuffersMap::const_iterator cbIterator = mResourceToBuffers[typeKey].find(pResource); + const ConstantBuffers* cb = (cbIterator != mResourceToBuffers[typeKey].end()) ? &(cbIterator->second) : NULL; + + D3D11RendererVariableBinder binder(d3dDeviceContext); + binder.bind(type, cb, mBindMode); + } +} + +void D3D11RendererVariableManager::setSharedVariable(const char* sharedBufferName, const char* variableName, const void* data, UINT size, UINT offset) +{ + NameVariablesMap::const_iterator svIt = mNameToSharedVariables.find(VariableKey(sharedBufferName, variableName)); + if (svIt != mNameToSharedVariables.end() && svIt->second) + { + D3D11SharedVariable* pSV = svIt->second; + RENDERER_ASSERT(pSV, "Invalid shared variable"); + internalSetVariable(pSV->m_pBuffer, pSV->getDataOffset()+offset, data, size ? size : pSV->getDataSize()); + } + else + { +#if RENDERER_ASSERT_SHARED_VARIABLE_EXISTS + RENDERER_ASSERT(0, "Shared variable has not been created!"); +#endif + } +} + +void D3D11RendererVariableManager::internalSetVariable(D3D11ConstantBuffer* pBuffer, PxU32 offset, const void* data, PxU32 size) +{ + RENDERER_ASSERT(pBuffer, "Invalid constant buffer"); + memcpy(pBuffer->data + offset, data, size); + pBuffer->bDirty = true; +} + +static RendererMaterial::VariableType getVariableType(const D3D11_SHADER_TYPE_DESC& desc) +{ + RendererMaterial::VariableType vt = RendererMaterial::NUM_VARIABLE_TYPES; + switch (desc.Type) + { + case D3D_SVT_INT: + if (desc.Rows == 1 && desc.Columns == 1) + { + vt = RendererMaterial::VARIABLE_INT; + } + break; + case D3D_SVT_FLOAT: + if (desc.Rows == 4 && desc.Columns == 4) + { + vt = RendererMaterial::VARIABLE_FLOAT4x4; + } + else if (desc.Rows == 1 && desc.Columns == 1) + { + vt = RendererMaterial::VARIABLE_FLOAT; + } + else if (desc.Rows == 1 && desc.Columns == 2) + { + vt = RendererMaterial::VARIABLE_FLOAT2; + } + else if (desc.Rows == 1 && desc.Columns == 3) + { + vt = RendererMaterial::VARIABLE_FLOAT3; + } + else if (desc.Rows == 1 && desc.Columns == 4) + { + vt = RendererMaterial::VARIABLE_FLOAT4; + } + break; + case D3D_SVT_SAMPLER2D: + vt = RendererMaterial::VARIABLE_SAMPLER2D; + break; + case D3D_SVT_SAMPLER3D: + vt = RendererMaterial::VARIABLE_SAMPLER3D; + break; + } + RENDERER_ASSERT(vt < RendererMaterial::NUM_VARIABLE_TYPES, "Unable to convert shader variable type."); + return vt; +} + +D3D11RendererVariableManager::D3D11ConstantBuffer* +D3D11RendererVariableManager::loadBuffer(std::vector<D3D11RendererMaterial::Variable*>& variables, + PxU32& variableBufferSize, + ShaderTypeKey typeKey, + ID3D11ShaderReflectionConstantBuffer* pReflectionBuffer, + const D3D11_SHADER_BUFFER_DESC& sbDesc, + const D3D11_BUFFER_DESC& cbDesc) +{ + ID3D11Buffer* pBuffer = NULL; + D3D11ConstantBuffer* pCB = NULL; + HRESULT result = mRenderer.getD3DDevice()->CreateBuffer(&cbDesc, NULL, &pBuffer); + RENDERER_ASSERT(SUCCEEDED(result), "Error creating D3D11 constant buffer."); + if (SUCCEEDED(result)) + { + pCB = new D3D11ConstantBuffer(pBuffer, new PxU8[sbDesc.Size], sbDesc.Size); + + try + { + for (PxU32 i = 0; i < sbDesc.Variables; ++i) + { + ID3D11ShaderReflectionVariable* pVariable = pReflectionBuffer->GetVariableByIndex(i); + D3D11_SHADER_VARIABLE_DESC vDesc; + pVariable->GetDesc(&vDesc); + + ID3D11ShaderReflectionType* pType = pVariable->GetType(); + D3D11_SHADER_TYPE_DESC tDesc; + pType->GetDesc(&tDesc); + + RendererMaterial::VariableType type = getVariableType(tDesc); + + D3D11DataVariable* var = 0; + + // Search to see if the variable already exists... + PxU32 numVariables = (PxU32)variables.size(); + for (PxU32 j = 0; j < numVariables; ++j) + { + if (!strcmp(variables[j]->getName(), vDesc.Name)) + { + var = static_cast<D3D11DataVariable*>(variables[j]); + break; + } + } + + // Check to see if the variable is of the same type. + if (var) + { + RENDERER_ASSERT(var->getType() == type, "Variable changes type!"); + } + + // If we couldn't find the variable... create a new variable... + if (!var) + { + var = new D3D11DataVariable(vDesc.Name, type, variableBufferSize); + variables.push_back(var); + variableBufferSize += var->getDataSize(); + } + + PxU8* varData = pCB->data + vDesc.StartOffset; + var->addHandle(typeKey, varData, &(pCB->bDirty)); + } + } + catch(...) + { + RENDERER_ASSERT(0, "Exception in processing D3D shader variables"); + delete pCB; + } + + } + return pCB; +} + +D3D11RendererVariableManager::D3D11ConstantBuffer* +D3D11RendererVariableManager::loadSharedBuffer(ShaderTypeKey typeKey, + ID3D11ShaderReflectionConstantBuffer* pReflectionBuffer, + const D3D11_SHADER_BUFFER_DESC& sbDesc, + const D3D11_BUFFER_DESC& cbDesc) +{ + D3D11ConstantBuffer* pCB = NULL; + // Check to see if the specified shared constant buffer has already been created + NameBuffersMap::iterator cbIt = mNameToSharedBuffer.find(sbDesc.Name); + if (cbIt != mNameToSharedBuffer.end()) + { + pCB = cbIt->second; + if( pCB ) + { + pCB->addref(); + } + } + else + { + ID3D11Buffer* pBuffer = NULL; + HRESULT result = mRenderer.getD3DDevice()->CreateBuffer(&cbDesc, NULL, &pBuffer); + RENDERER_ASSERT(SUCCEEDED(result), "Error creating D3D11 constant buffer."); + if (SUCCEEDED(result)) + { + pCB = new D3D11ConstantBuffer(pBuffer, new PxU8[sbDesc.Size], sbDesc.Size); + for (PxU32 i = 0; i < sbDesc.Variables; ++i) + { + ID3D11ShaderReflectionVariable* pVariable = pReflectionBuffer->GetVariableByIndex(i); + D3D11_SHADER_VARIABLE_DESC vDesc; + pVariable->GetDesc(&vDesc); + + ID3D11ShaderReflectionType* pType = pVariable->GetType(); + D3D11_SHADER_TYPE_DESC tDesc; + pType->GetDesc(&tDesc); + + mVariables.push_back(new D3D11SharedVariable(vDesc.Name, getVariableType(tDesc), vDesc.StartOffset, pCB)); + mNameToSharedVariables[VariableKey(sbDesc.Name, vDesc.Name)] = mVariables.back(); + } + mNameToSharedBuffer[sbDesc.Name] = pCB; + } + } + + return pCB; +} + +void D3D11RendererVariableManager::loadVariables(D3D11RendererMaterial* pMaterial, + ID3DBlob* pShader, + D3DType type, + RendererMaterial::Pass pass) +{ + D3DX11* pD3DX = mRenderer.getD3DX11(); + RENDERER_ASSERT(pD3DX, "Invalid D3D11 shader compiler"); + + ID3D11ShaderReflection* pReflection = NULL; + HRESULT result = pD3DX->reflect(pShader->GetBufferPointer(), + pShader->GetBufferSize(), + IID_ID3D11ShaderReflection, + (void**) &pReflection); + + RENDERER_ASSERT(SUCCEEDED(result) && pReflection, "Failure in processing D3D11 shader reflection") + if (SUCCEEDED(result) && pReflection) + { + loadConstantVariables(pMaterial, pShader, getShaderTypeKey(type, pass), pReflection, &pMaterial->m_variables, &pMaterial->m_variableBufferSize); + loadTextureVariables(pMaterial, pShader, getShaderTypeKey(type, pass), pReflection); + } +} + +void D3D11RendererVariableManager::loadSharedVariables(const void* pResource, + ID3DBlob* pShader, + D3DType type, + RendererMaterial::Pass pass) +{ + D3DX11* pD3DX = mRenderer.getD3DX11(); + RENDERER_ASSERT(pD3DX, "Invalid D3D11 shader compiler"); + + ID3D11ShaderReflection* pReflection = NULL; + HRESULT result = pD3DX->reflect(pShader->GetBufferPointer(), + pShader->GetBufferSize(), + IID_ID3D11ShaderReflection, + (void**) &pReflection); + + RENDERER_ASSERT(SUCCEEDED(result) && pReflection, "Failure in processing D3D11 shader reflection") + if (SUCCEEDED(result) && pReflection) + { + loadConstantVariables(pResource, pShader, getShaderTypeKey(type, pass), pReflection); + } +} + +void D3D11RendererVariableManager::loadConstantVariables(const void* pResource, + ID3DBlob* pShader, + ShaderTypeKey typeKey, + ID3D11ShaderReflection* pReflection, + MaterialVariables* pVariables, + PxU32* pVariableBufferSize) +{ + D3D11_SHADER_DESC desc; + pReflection->GetDesc(&desc); + + for (PxU32 i = 0; i < desc.ConstantBuffers; ++i) + { + D3D11_BUFFER_DESC cbDesc; + cbDesc.CPUAccessFlags = (mBindMode == BIND_MAP) ? D3D11_CPU_ACCESS_WRITE : 0; + cbDesc.Usage = (mBindMode == BIND_MAP) ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT; + cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + cbDesc.MiscFlags = 0; + + ID3D11ShaderReflectionConstantBuffer* pConstBuffer = pReflection->GetConstantBufferByIndex(i); + + D3D11_SHADER_BUFFER_DESC sbDesc; + pConstBuffer->GetDesc(&sbDesc); + cbDesc.ByteWidth = sbDesc.Size; + + D3D11ConstantBuffer* pCB = NULL; + // Check to see if the constant buffer's name has been specified as s shared buffer + if (mSharedBufferNames.find(sbDesc.Name) != mSharedBufferNames.end()) + { + pCB = loadSharedBuffer(typeKey, pConstBuffer, sbDesc, cbDesc); + } + else if (pVariables && pVariableBufferSize) + { + pCB = loadBuffer(*pVariables, *pVariableBufferSize, typeKey, pConstBuffer, sbDesc, cbDesc); + } + else + { + RENDERER_ASSERT(0, "Only materials support non-shared variables."); + } + + RENDERER_ASSERT(pCB, "Error creating shared buffer"); + if (pCB) + { + mResourceToBuffers[typeKey][pResource].push_back(pCB); + } + } +} + +RendererMaterial::VariableType getTextureVariableType(const D3D11_SHADER_INPUT_BIND_DESC& resourceDesc) +{ + switch (resourceDesc.Dimension) + { + case D3D_SRV_DIMENSION_TEXTURE1D: + case D3D_SRV_DIMENSION_TEXTURE2D: + return RendererMaterial::VARIABLE_SAMPLER2D; + case D3D_SRV_DIMENSION_TEXTURE3D: + return RendererMaterial::VARIABLE_SAMPLER3D; + default: + RENDERER_ASSERT(0, "Invalid texture type."); + return RendererMaterial::NUM_VARIABLE_TYPES; + } +} + +void D3D11RendererVariableManager::loadTextureVariables(D3D11RendererMaterial* pMaterial, + ID3DBlob* pShader, + ShaderTypeKey typeKey, + ID3D11ShaderReflection* pReflection) +{ + D3D11_SHADER_DESC desc; + pReflection->GetDesc(&desc); + + // Load texture variables for the specified shader + for (PxU32 i = 0; i < desc.BoundResources; ++i) + { + D3D11_SHADER_INPUT_BIND_DESC resourceDesc; + HRESULT result = pReflection->GetResourceBindingDesc(i, &resourceDesc); + if (SUCCEEDED(result) && resourceDesc.Type == D3D10_SIT_TEXTURE) + { + D3D11TextureVariable* var = NULL; + // Search to see if the variable already exists... + PxU32 numVariables = (PxU32)pMaterial->m_variables.size(); + for (PxU32 j = 0; j < numVariables; ++j) + { + if (!strcmp(pMaterial->m_variables[j]->getName(), resourceDesc.Name)) + { + var = static_cast<D3D11TextureVariable*>(pMaterial->m_variables[j]); + break; + } + } + + RendererMaterial::VariableType varType = getTextureVariableType(resourceDesc); + + // Check to see if the variable is of the same type. + if (var) + { + RENDERER_ASSERT(var->getType() == varType, "Variable changes type!"); + } + + // If we couldn't find the variable... create a new variable... + if (!var && (varType == RendererMaterial::VARIABLE_SAMPLER2D || varType == RendererMaterial::VARIABLE_SAMPLER3D) ) + { + var = new D3D11TextureVariable(resourceDesc.Name, varType, pMaterial->m_variableBufferSize); + pMaterial->m_variables.push_back(var); + pMaterial->m_variableBufferSize += var->getDataSize(); + } + + var->addHandle(typeKey, resourceDesc.BindPoint); + } + } +} + +void D3D11RendererVariableManager::unloadVariables( const void* pResource ) +{ + for (PxU32 i = 0; i < NUM_SHADER_TYPES; ++i) + { + ResourceBuffersMap::iterator it = mResourceToBuffers[i].find(pResource); + if (it != mResourceToBuffers[i].end()) + { + for (PxU32 j = 0; j < it->second.size(); ++j) + { + it->second[j]->release(); + } + mResourceToBuffers[i].erase(it); + } + } +} +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererVariableManager.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererVariableManager.h new file mode 100644 index 00000000..fdd8a86c --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererVariableManager.h @@ -0,0 +1,152 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D11_RENDERER_VARIABLE_MANAGER_H +#define D3D11_RENDERER_VARIABLE_MANAGER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include <RendererMaterial.h> + +#include "D3D11RendererMaterial.h" +#include "D3D11RendererTraits.h" +#include "D3D11RendererUtils.h" +#include "D3Dcompiler.h" + +#include <set> +#include <string> +#include <limits> + +// Enable to check that binding a shared variable by name actually +// finds the specified shared variable +#define RENDERER_ASSERT_SHARED_VARIABLE_EXISTS 0 + +namespace SampleRenderer +{ + +static const PxU32 NUM_SHADER_TYPES = D3DTypes::NUM_SHADER_TYPES + RendererMaterial::NUM_PASSES; + +class D3D11RendererVariableManager +{ +public: + enum SharedVariableSize + { + USE_DEFAULT = 0, + }; + + enum BindMode + { + BIND_MAP = 0, + BIND_SUBRESOURCE + }; + +public: + typedef std::set<std::string> StringSet; + + D3D11RendererVariableManager(D3D11Renderer& renderer, StringSet& cbNames, BindMode bindMode = BIND_SUBRESOURCE); + virtual ~D3D11RendererVariableManager(void); + +public: + void bind(const void* pResource, D3DType shaderType, RendererMaterial::Pass pass = RendererMaterial::NUM_PASSES) const; + void setSharedVariable(const char* sharedBufferName, const char* variableName, const void* data, UINT size = USE_DEFAULT, UINT offset = 0); + void loadVariables(D3D11RendererMaterial* pMaterial, ID3DBlob* pShader, D3DType shaderType, RendererMaterial::Pass pass = RendererMaterial::NUM_PASSES); + void loadSharedVariables(const void* pResource, ID3DBlob* pShader, D3DType shaderType, RendererMaterial::Pass pass = RendererMaterial::NUM_PASSES); + void unloadVariables(const void* pResource); + + class D3D11ConstantBuffer; + class D3D11DataVariable; + class D3D11TextureVariable; + class D3D11SharedVariable; + + typedef std::vector<D3D11ConstantBuffer*> ConstantBuffers; + typedef std::vector<ID3D11Buffer*> D3DBuffers; + typedef std::vector<D3D11SharedVariable*> Variables; + typedef std::vector<D3D11RendererMaterial::Variable*> MaterialVariables; + + typedef D3D11StringKey StringKey; + typedef const void* ResourceKey; + typedef PxU32 ShaderTypeKey; + typedef std::pair<StringKey, StringKey> VariableKey; + + typedef std::map<StringKey, D3D11ConstantBuffer*> NameBuffersMap; + typedef std::map<VariableKey, D3D11SharedVariable*> NameVariablesMap; + typedef std::map<ResourceKey, ConstantBuffers> ResourceBuffersMap; + + typedef ConstantBuffers::const_iterator CBIterator; + +private: + D3D11RendererVariableManager& operator=(const D3D11RendererVariableManager&) + { + return *this; + } + + D3D11ConstantBuffer* loadBuffer(MaterialVariables& variables, + PxU32& variableBufferSize, + ShaderTypeKey typeKey, + ID3D11ShaderReflectionConstantBuffer* pReflectionBuffer, + const D3D11_SHADER_BUFFER_DESC& sbDesc, + const D3D11_BUFFER_DESC& cbDesc); + D3D11ConstantBuffer* loadSharedBuffer(ShaderTypeKey typeKey, + ID3D11ShaderReflectionConstantBuffer* pReflectionBuffer, + const D3D11_SHADER_BUFFER_DESC& sbDesc, + const D3D11_BUFFER_DESC& cbDesc); + + void loadConstantVariables(const void* pResource, + ID3DBlob* pShader, + ShaderTypeKey typeKey, + ID3D11ShaderReflection* pReflection, + MaterialVariables* pVariables = NULL, + PxU32* pVariableBufferSize = NULL); + void loadTextureVariables(D3D11RendererMaterial* pMaterial, + ID3DBlob* pShader, + ShaderTypeKey typeKey, + ID3D11ShaderReflection* pReflection); + + void internalSetVariable(D3D11ConstantBuffer* pBuffer, PxU32 offset, const void* data, PxU32 size); + void updateVariables(const ConstantBuffers*) const; + void bindVariables(const ConstantBuffers*, bool bFragment) const; + +private: + + D3D11Renderer& mRenderer; + StringSet mSharedBufferNames; + + BindMode mBindMode; + + Variables mVariables; + + NameBuffersMap mNameToSharedBuffer; + NameVariablesMap mNameToSharedVariables; + + ResourceBuffersMap mResourceToBuffers[NUM_SHADER_TYPES]; +}; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererVertexBuffer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererVertexBuffer.cpp new file mode 100644 index 00000000..88c6ba25 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererVertexBuffer.cpp @@ -0,0 +1,374 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include "D3D11RendererVertexBuffer.h" +#include <RendererVertexBufferDesc.h> + +#if PX_WINDOWS +#include <task/PxTask.h> +#endif + +using namespace SampleRenderer; + +static D3D_FEATURE_LEVEL gFeatureLevel = D3D_FEATURE_LEVEL_9_1; + +static D3D11_INPUT_ELEMENT_DESC buildVertexElement(LPCSTR name, UINT index, DXGI_FORMAT format, UINT inputSlot, UINT alignedByOffset, D3D11_INPUT_CLASSIFICATION inputSlotClass, UINT instanceDataStepRate) +{ + D3D11_INPUT_ELEMENT_DESC element; + element.SemanticName = name; + element.SemanticIndex = index; + element.Format = format; + element.InputSlot = inputSlot; + element.AlignedByteOffset = alignedByOffset; + element.InputSlotClass = inputSlotClass; + element.InstanceDataStepRate = instanceDataStepRate; + return element; +} + +static DXGI_FORMAT getD3DFormat(RendererVertexBuffer::Format format) +{ + DXGI_FORMAT d3dFormat = DXGI_FORMAT_UNKNOWN; + if(gFeatureLevel <= D3D_FEATURE_LEVEL_9_3) + { + switch (format) + { + case RendererVertexBuffer::FORMAT_FLOAT1: + d3dFormat = DXGI_FORMAT_R32_FLOAT; + break; + case RendererVertexBuffer::FORMAT_FLOAT2: + d3dFormat = DXGI_FORMAT_R32G32_FLOAT; + break; + case RendererVertexBuffer::FORMAT_FLOAT3: + d3dFormat = DXGI_FORMAT_R32G32B32_FLOAT; + break; + case RendererVertexBuffer::FORMAT_FLOAT4: + d3dFormat = DXGI_FORMAT_R32G32B32A32_FLOAT; + break; + case RendererVertexBuffer::FORMAT_UBYTE4: + d3dFormat = DXGI_FORMAT_R8G8B8A8_UINT; + break; + case RendererVertexBuffer::FORMAT_USHORT4: + d3dFormat = DXGI_FORMAT_R16G16B16A16_UINT; + break; + case RendererVertexBuffer::FORMAT_COLOR_BGRA: + d3dFormat = DXGI_FORMAT_R8G8B8A8_UINT; + break; + case RendererVertexBuffer::FORMAT_COLOR_RGBA: + d3dFormat = DXGI_FORMAT_R8G8B8A8_UINT; + break; + case RendererVertexBuffer::FORMAT_COLOR_NATIVE: + d3dFormat = DXGI_FORMAT_R32_FLOAT; + break; + } + } + else + { + switch (format) + { + case RendererVertexBuffer::FORMAT_FLOAT1: + d3dFormat = DXGI_FORMAT_R32_FLOAT; + break; + case RendererVertexBuffer::FORMAT_FLOAT2: + d3dFormat = DXGI_FORMAT_R32G32_FLOAT; + break; + case RendererVertexBuffer::FORMAT_FLOAT3: + d3dFormat = DXGI_FORMAT_R32G32B32_FLOAT; + break; + case RendererVertexBuffer::FORMAT_FLOAT4: + d3dFormat = DXGI_FORMAT_R32G32B32A32_FLOAT; + break; + case RendererVertexBuffer::FORMAT_UBYTE4: + d3dFormat = DXGI_FORMAT_R8G8B8A8_UINT; + break; + case RendererVertexBuffer::FORMAT_USHORT4: + d3dFormat = DXGI_FORMAT_R16G16B16A16_UINT; + break; + case RendererVertexBuffer::FORMAT_COLOR_BGRA: + d3dFormat = DXGI_FORMAT_B8G8R8A8_UNORM; + break; + case RendererVertexBuffer::FORMAT_COLOR_RGBA: + d3dFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + break; + case RendererVertexBuffer::FORMAT_COLOR_NATIVE: + //d3dFormat = DXGI_FORMAT_R32G32B32_FLOAT; + d3dFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + break; + } + } + RENDERER_ASSERT(d3dFormat != DXGI_FORMAT_UNKNOWN, "Invalid DIRECT3D11 vertex type."); + return d3dFormat; +} + +static void getD3DUsage(RendererVertexBuffer::Semantic semantic, LPCSTR& usageName, PxU8& usageIndex) +{ + usageName = "POSITION"; + usageIndex = 0; + if (semantic >= RendererVertexBuffer::SEMANTIC_TEXCOORD0 && semantic <= RendererVertexBuffer::SEMANTIC_TEXCOORDMAX) + { + usageName = "TEXCOORD"; + usageIndex = (PxU8)(semantic - RendererVertexBuffer::SEMANTIC_TEXCOORD0); + } + else + { + switch (semantic) + { + case RendererVertexBuffer::SEMANTIC_POSITION: + usageName = "POSITION"; + break; + case RendererVertexBuffer::SEMANTIC_NORMAL: + usageName = "NORMAL"; + break; + case RendererVertexBuffer::SEMANTIC_TANGENT: + usageName = "TANGENT"; + break; + case RendererVertexBuffer::SEMANTIC_COLOR: + usageName = "COLOR"; + break; + case RendererVertexBuffer::SEMANTIC_BONEINDEX: + usageName = "TEXCOORD"; + usageIndex = RENDERER_BONEINDEX_CHANNEL; + break; + case RendererVertexBuffer::SEMANTIC_BONEWEIGHT: + usageName = "TEXCOORD"; + usageIndex = RENDERER_BONEWEIGHT_CHANNEL; + break; + case RendererVertexBuffer::SEMANTIC_DISPLACEMENT_TEXCOORD: + usageName = "TEXCOORD"; + usageIndex = RENDERER_DISPLACEMENT_CHANNEL; + break; + case RendererVertexBuffer::SEMANTIC_DISPLACEMENT_FLAGS: + usageName = "TEXCOORD"; + usageIndex = RENDERER_DISPLACEMENT_FLAGS_CHANNEL; + break; + } + } +} + +D3D11RendererVertexBuffer::D3D11RendererVertexBuffer(ID3D11Device& d3dDevice, ID3D11DeviceContext& d3dDeviceContext, const RendererVertexBufferDesc& desc, bool bUseMapForLocking) : + RendererVertexBuffer(desc), + m_d3dDevice(d3dDevice), + m_d3dDeviceContext(d3dDeviceContext), + m_d3dVertexBuffer(NULL), + m_bUseMapForLocking(bUseMapForLocking && (!desc.registerInCUDA)), + m_buffer(NULL) +{ + gFeatureLevel = d3dDevice.GetFeatureLevel(); + + memset(&m_d3dBufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + m_d3dBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + m_d3dBufferDesc.ByteWidth = (UINT)(desc.maxVertices * m_stride); + + if (m_bUseMapForLocking) + { + m_d3dBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + m_d3dBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + } + else + { + m_d3dBufferDesc.CPUAccessFlags = 0; + m_d3dBufferDesc.Usage = D3D11_USAGE_DEFAULT; + m_buffer = new PxU8[m_d3dBufferDesc.ByteWidth]; + memset(m_buffer, 0, sizeof(PxU8)*m_d3dBufferDesc.ByteWidth); + } + + m_bBufferWritten = false; + + onDeviceReset(); + + if (m_d3dVertexBuffer) + { + m_maxVertices = desc.maxVertices; + } +} + +D3D11RendererVertexBuffer::~D3D11RendererVertexBuffer(void) +{ + if (m_d3dVertexBuffer) + { +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if (m_interopContext && m_registeredInCUDA) + { + m_registeredInCUDA = !m_interopContext->unregisterResourceInCuda(m_InteropHandle); + } +#endif + m_d3dVertexBuffer->Release(); + m_d3dVertexBuffer = NULL; + } + + delete [] m_buffer; +} + +void D3D11RendererVertexBuffer::addVertexElements(PxU32 streamIndex, std::vector<D3D11_INPUT_ELEMENT_DESC> &vertexElements) const +{ + for (PxU32 i = 0; i < NUM_SEMANTICS; i++) + { + Semantic semantic = (Semantic)i; + const SemanticDesc& sm = m_semanticDescs[semantic]; + if (sm.format < NUM_FORMATS) + { + PxU8 d3dUsageIndex = 0; + LPCSTR d3dUsageName = ""; + getD3DUsage(semantic, d3dUsageName, d3dUsageIndex); + vertexElements.push_back(buildVertexElement(d3dUsageName, + d3dUsageIndex, + getD3DFormat(sm.format), + streamIndex, + (UINT)sm.offset, + D3D11_INPUT_PER_VERTEX_DATA, + 0)); + } + } +} + +void D3D11RendererVertexBuffer::swizzleColor(void* colors, PxU32 stride, PxU32 numColors, RendererVertexBuffer::Format inFormat) +{ +/* + if (inFormat == RendererVertexBuffer::FORMAT_COLOR_BGRA) + { + const void* end = ((PxU8*)colors) + (stride * numColors); + for (PxU8* iterator = (PxU8*)colors; iterator < end; iterator += stride) + { + std::swap(((PxU8*)iterator)[0], ((PxU8*)iterator)[2]); + } + } +*/ +} + +void* D3D11RendererVertexBuffer::lock(void) +{ + // For now NO_OVERWRITE is the only mapping that functions properly + return internalLock(getHint() == HINT_STATIC ? /* D3D11_MAP_WRITE_DISCARD */ D3D11_MAP_WRITE_NO_OVERWRITE : D3D11_MAP_WRITE_NO_OVERWRITE); +} + +void* D3D11RendererVertexBuffer::internalLock(D3D11_MAP MapType) +{ + void* lockedBuffer = 0; + if (m_d3dVertexBuffer) + { + if (m_bUseMapForLocking) + { + D3D11_MAPPED_SUBRESOURCE mappedRead; + m_d3dDeviceContext.Map(m_d3dVertexBuffer, 0, MapType, NULL, &mappedRead); + RENDERER_ASSERT(mappedRead.pData, "Failed to lock DIRECT3D11 Vertex Buffer."); + lockedBuffer = mappedRead.pData; + } + else + { + lockedBuffer = m_buffer; + } + } + m_bBufferWritten = true; + return lockedBuffer; +} + +void D3D11RendererVertexBuffer::unlock(void) +{ + if (m_d3dVertexBuffer) + { + if (m_bUseMapForLocking) + { + m_d3dDeviceContext.Unmap(m_d3dVertexBuffer, 0); + } + else + { + m_d3dDeviceContext.UpdateSubresource(m_d3dVertexBuffer, 0, NULL, m_buffer, m_d3dBufferDesc.ByteWidth, 0); + } + } +} + +void D3D11RendererVertexBuffer::bind(PxU32 streamID, PxU32 firstVertex) +{ + prepareForRender(); + if (m_d3dVertexBuffer) + { + ID3D11Buffer* pBuffers[1] = { m_d3dVertexBuffer }; + UINT strides[1] = { m_stride }; + UINT offsets[1] = { firstVertex* m_stride }; + m_d3dDeviceContext.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); + } +} + +void D3D11RendererVertexBuffer::unbind(PxU32 streamID) +{ + ID3D11Buffer* pBuffers[1] = { NULL }; + UINT strides[1] = { 0 }; + UINT offsets[1] = { 0 }; + m_d3dDeviceContext.IASetVertexBuffers(streamID, 1, pBuffers, strides, offsets); +} + +void D3D11RendererVertexBuffer::onDeviceLost(void) +{ +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if (m_interopContext && m_registeredInCUDA) + { + m_interopContext->unregisterResourceInCuda(m_InteropHandle); + } +#endif + + m_registeredInCUDA = false; + + if (m_d3dVertexBuffer) + { + m_d3dVertexBuffer->Release(); + m_d3dVertexBuffer = 0; + } +} + +void D3D11RendererVertexBuffer::onDeviceReset(void) +{ + if (!m_d3dVertexBuffer) + { + m_d3dDevice.CreateBuffer(&m_d3dBufferDesc, NULL, &m_d3dVertexBuffer); + RENDERER_ASSERT(m_d3dVertexBuffer, "Failed to create DIRECT3D11 Vertex Buffer."); +#if PX_WINDOWS && PX_SUPPORT_GPU_PHYSX + if (m_interopContext && m_d3dVertexBuffer && m_mustBeRegisteredInCUDA) + { + RENDERER_ASSERT(m_deferredUnlock == false, "Deferred VB Unlock must be disabled when CUDA Interop is in use.") + m_registeredInCUDA = m_interopContext->registerResourceInCudaD3D(m_InteropHandle, m_d3dVertexBuffer); + } +#endif + m_bBufferWritten = false; + } +} + +bool D3D11RendererVertexBuffer::checkBufferWritten(void) +{ + if (m_InteropHandle) + { + return true; + } + else + { + return m_bBufferWritten; + } +} + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererVertexBuffer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererVertexBuffer.h new file mode 100644 index 00000000..e37e27e3 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/d3d11/D3D11RendererVertexBuffer.h @@ -0,0 +1,79 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#ifndef D3D11_RENDERER_VERTEXBUFFER_H +#define D3D11_RENDERER_VERTEXBUFFER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_DIRECT3D11) + +#include <RendererVertexBuffer.h> +#include "D3D11Renderer.h" + +namespace SampleRenderer +{ + +class D3D11RendererVertexBuffer : public RendererVertexBuffer, public D3D11RendererResource +{ + friend class D3D11Renderer; +public: + D3D11RendererVertexBuffer(ID3D11Device& d3dDevice, ID3D11DeviceContext& d3dDeviceContext, const RendererVertexBufferDesc& desc, bool bUseMapForLocking = TRUE); + virtual ~D3D11RendererVertexBuffer(void); + + void addVertexElements(PxU32 streamIndex, std::vector<D3D11_INPUT_ELEMENT_DESC> &vertexElements) const; + + virtual bool checkBufferWritten(void); + +protected: + virtual void swizzleColor(void* colors, PxU32 stride, PxU32 numColors, RendererVertexBuffer::Format inFormat); + + virtual void* lock(void); + virtual void unlock(void); + + virtual void bind(PxU32 streamID, PxU32 firstVertex); + virtual void unbind(PxU32 streamID); + +private: + virtual void onDeviceLost(void); + virtual void onDeviceReset(void); + + void* internalLock(D3D11_MAP MapType); + +private: + ID3D11Device& m_d3dDevice; + ID3D11DeviceContext& m_d3dDeviceContext; + ID3D11Buffer* m_d3dVertexBuffer; + D3D11_BUFFER_DESC m_d3dBufferDesc; + bool m_bUseMapForLocking; + PxU8* m_buffer; + bool m_bBufferWritten; +}; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D11) +#endif |