| | |
| | #define NOMINMAX |
| |
|
| | #include "meshRendererD3D12.h" |
| |
|
| | |
| |
|
| | #include "meshRenderPipelineD3D12.h" |
| | #include "pointRenderPipelineD3D12.h" |
| | #include "fluidThicknessRenderPipelineD3D12.h" |
| | #include "fluidEllipsoidRenderPipelineD3D12.h" |
| | #include "fluidSmoothRenderPipelineD3D12.h" |
| | #include "fluidCompositeRenderPipelineD3D12.h" |
| | #include "diffusePointRenderPipelineD3D12.h" |
| | #include "lineRenderPipelineD3D12.h" |
| |
|
| | #include "meshUtil.h" |
| |
|
| | #include <NvCoDx12RenderTarget.h> |
| |
|
| | |
| | #include <SDL_syswm.h> |
| |
|
| | #include "shadersDemoContext.h" |
| |
|
| | |
| | #include "core/maths.h" |
| | #include "core/extrude.h" |
| |
|
| | #define NOMINMAX |
| | #include <d3d12.h> |
| | #include <d3dcompiler.h> |
| |
|
| | #include "imguiGraphD3D12.h" |
| |
|
| | #include "../d3d/loader.h" |
| |
|
| | #include "demoContextD3D12.h" |
| |
|
| | |
| | #pragma comment (lib, "d3d12.lib") |
| | #pragma comment (lib, "DXGI.lib") |
| |
|
| | using namespace DirectX; |
| |
|
| | static float gSpotMin = 0.5f; |
| | static float gSpotMax = 1.0f; |
| | static float gShadowBias = 0.075f; |
| | static const int kShadowResolution = 2048; |
| |
|
| | |
| | extern Colour g_colors[]; |
| |
|
| | #define NV_PRINT_F_U64 "%I64u" |
| |
|
| | DemoContext* CreateDemoContextD3D12() |
| | { |
| | return new FlexSample::DemoContextD3D12; |
| | } |
| |
|
| | namespace FlexSample { |
| |
|
| | DemoContextD3D12::DemoContextD3D12() |
| | { |
| | m_shadowMapLinearSamplerIndex = -1; |
| | m_fluidPointDepthSrvIndex = -1; |
| | m_currentShadowMap = nullptr; |
| | m_targetShadowMap = nullptr; |
| | |
| | m_inLineDraw = false; |
| | memset(&m_meshDrawParams, 0, sizeof(m_meshDrawParams)); |
| |
|
| | m_hwnd = nullptr; |
| | m_window = nullptr; |
| |
|
| | |
| | m_debugLineVertices.resize(MAX_DEBUG_LINE_SIZE); |
| |
|
| | m_renderStateManager = new RenderStateManagerD3D12; |
| | } |
| |
|
| | template <class T> |
| | void inline COMRelease(T& t) |
| | { |
| | if (t) t->Release(); |
| | t = nullptr; |
| | } |
| |
|
| | DemoContextD3D12::~DemoContextD3D12() |
| | { |
| | imguiGraphDestroy(); |
| |
|
| | AppGraphCtxRelease(m_appGraphCtx); |
| |
|
| | delete m_renderStateManager; |
| |
|
| | COMRelease(m_graphicsCompleteFence); |
| | COMRelease(m_queryHeap); |
| | COMRelease(m_queryResults); |
| |
|
| | COMRelease(m_bufferStage); |
| |
|
| | |
| | m_meshPipeline.reset(); |
| | m_pointPipeline.reset(); |
| | m_fluidPointPipeline.reset(); |
| | m_fluidSmoothPipeline.reset(); |
| | m_fluidCompositePipeline.reset(); |
| | m_diffusePointPipeline.reset(); |
| | m_linePipeline.reset(); |
| | m_fluidThicknessRenderTarget.reset(); |
| | m_fluidPointRenderTarget.reset(); |
| | m_fluidSmoothRenderTarget.reset(); |
| | m_fluidResolvedTarget.reset(); |
| | m_screenQuadMesh.reset(); |
| | m_shadowMap.reset(); |
| | } |
| |
|
| | bool DemoContextD3D12::initialize(const RenderInitOptions& options) |
| | { |
| | |
| | m_msaaSamples = Max(1, options.numMsaaSamples); |
| |
|
| | { |
| | |
| | loadModules(APP_CONTEXT_D3D12); |
| | } |
| |
|
| | m_appGraphCtx = AppGraphCtxCreate(0); |
| | m_renderContext = cast_to_AppGraphCtxD3D12(m_appGraphCtx); |
| |
|
| | AppGraphCtxUpdateSize(m_appGraphCtx, options.window, options.fullscreen, m_msaaSamples); |
| |
|
| | using namespace NvCo; |
| | |
| | m_hwnd = nullptr; |
| | m_window = options.window; |
| | { |
| | |
| | SDL_SysWMinfo winInfo; |
| | SDL_VERSION(&winInfo.version); |
| | if (SDL_GetWindowWMInfo(options.window, &winInfo)) |
| | { |
| | if (winInfo.subsystem == SDL_SYSWM_WINDOWS) |
| | { |
| | m_hwnd = winInfo.info.win.window; |
| | } |
| | } |
| | } |
| |
|
| | { |
| | WCHAR buffer[_MAX_PATH]; |
| | DWORD size = GetModuleFileNameW(nullptr, buffer, _MAX_PATH); |
| | if (size == 0 || size == _MAX_PATH) |
| | { |
| | |
| | return false; |
| | } |
| | std::wstring path; |
| | path += buffer; |
| | const size_t lastSlash = path.find_last_of(L"\\"); |
| | if (lastSlash >= 0) |
| | { |
| | path.resize(lastSlash + 1); |
| | } |
| |
|
| | m_executablePath.swap(path); |
| | } |
| |
|
| | { |
| | m_shadersPath = m_executablePath; |
| | m_shadersPath += L"../../demo/d3d/shaders/"; |
| | } |
| | |
| | int width, height; |
| | SDL_GetWindowSize(m_window, &width, &height); |
| |
|
| | { |
| | ScopeGpuWork scope(getRenderContext()); |
| | NV_RETURN_FALSE_ON_FAIL(_initRenderResources(options)); |
| |
|
| | { |
| | |
| | ImguiGraphDescD3D12 desc; |
| | desc.device = m_renderContext->m_device; |
| | desc.commandList = m_renderContext->m_commandList; |
| | desc.lastFenceCompleted = 0; |
| | desc.nextFenceValue = 1; |
| | desc.winW = m_renderContext->m_winW; |
| | desc.winW = m_renderContext->m_winH; |
| | desc.numMSAASamples = options.numMsaaSamples; |
| | desc.dynamicHeapCbvSrvUav.userdata = this; |
| | desc.dynamicHeapCbvSrvUav.reserveDescriptors = NULL; |
| |
|
| | int defaultFontHeight = (options.defaultFontHeight <= 0) ? 15 : options.defaultFontHeight; |
| | |
| | if (!imguiGraphInit("../../data/DroidSans.ttf", float(defaultFontHeight), (ImguiGraphDesc*)&desc)) |
| | { |
| | return false; |
| | } |
| | } |
| | } |
| |
|
| | return true; |
| | } |
| |
|
| | int DemoContextD3D12::_initRenderResources(const RenderInitOptions& options) |
| | { |
| | AppGraphCtxD3D12* renderContext = getRenderContext(); |
| | ID3D12Device* device = renderContext->m_device; |
| |
|
| | { |
| | |
| | |
| | D3D12_FEATURE_DATA_D3D12_OPTIONS options; |
| | device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options)); |
| | } |
| |
|
| | { |
| | |
| | NV_RETURN_ON_FAIL(m_renderStateManager->initialize(renderContext, 16 * 1024 * 1024)); |
| | m_renderState = m_renderStateManager->getState(); |
| | } |
| |
|
| | |
| | { |
| | std::unique_ptr<MeshRendererD3D12> renderer(new MeshRendererD3D12); |
| | NV_RETURN_ON_FAIL(renderer->initialize(m_renderState)); |
| | m_meshRenderer = std::move(renderer); |
| | } |
| |
|
| | { |
| | |
| | m_linearSamplerIndex = m_renderState.m_samplerDescriptorHeap->allocate(); |
| | m_shadowMapLinearSamplerIndex = m_renderState.m_samplerDescriptorHeap->allocate(); |
| |
|
| | { |
| | |
| | D3D12_SAMPLER_DESC desc = |
| | { |
| | D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT, |
| | D3D12_TEXTURE_ADDRESS_MODE_CLAMP, |
| | D3D12_TEXTURE_ADDRESS_MODE_CLAMP, |
| | D3D12_TEXTURE_ADDRESS_MODE_CLAMP, |
| | 0.0f, 0, D3D12_COMPARISON_FUNC_LESS_EQUAL, |
| | 0.0f, 0.0f, 0.0f, 0.0f, |
| | 0.0f, 0.0f, |
| | }; |
| | device->CreateSampler(&desc, m_renderState.m_samplerDescriptorHeap->getCpuHandle(m_shadowMapLinearSamplerIndex)); |
| | } |
| | { |
| | |
| | D3D12_SAMPLER_DESC desc = |
| | { |
| | D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT, |
| | D3D12_TEXTURE_ADDRESS_MODE_CLAMP, |
| | D3D12_TEXTURE_ADDRESS_MODE_CLAMP, |
| | D3D12_TEXTURE_ADDRESS_MODE_CLAMP, |
| | 0.0, 0, D3D12_COMPARISON_FUNC_NEVER, |
| | 0.0f, 0.0f, 0.0f, 0.0f, |
| | 0.0f, 0.0f, |
| | }; |
| | device->CreateSampler(&desc, m_renderState.m_samplerDescriptorHeap->getCpuHandle(m_linearSamplerIndex)); |
| | } |
| | } |
| |
|
| | |
| | { |
| | m_fluidPointDepthSrvIndex = m_renderState.m_srvCbvUavDescriptorHeap->allocate(); |
| | m_fluidCompositeSrvBaseIndex = m_renderState.m_srvCbvUavDescriptorHeap->allocate(NUM_COMPOSITE_SRVS); |
| | } |
| |
|
| | |
| | { |
| | m_shadowMap = std::unique_ptr<NvCo::Dx12RenderTarget>(new NvCo::Dx12RenderTarget); |
| |
|
| | NvCo::Dx12RenderTarget::Desc desc; |
| | desc.init(kShadowResolution, kShadowResolution); |
| | desc.m_targetFormat = DXGI_FORMAT_UNKNOWN; |
| | desc.m_depthStencilFormat = DXGI_FORMAT_R32_TYPELESS; |
| |
|
| | |
| | NV_RETURN_ON_FAIL(m_shadowMap->init(renderContext, desc)); |
| |
|
| | m_shadowMap->setDebugName(L"ShadowMap"); |
| |
|
| | if (m_shadowMap->allocateSrvView(NvCo::Dx12RenderTarget::BUFFER_DEPTH_STENCIL, device, *m_renderState.m_srvCbvUavDescriptorHeap) < 0) |
| | { |
| | printf("Unable to allocate shadow buffer srv index"); |
| |
|
| | return NV_FAIL; |
| | } |
| | } |
| |
|
| | |
| | NV_RETURN_ON_FAIL(_initFluidRenderTargets()); |
| |
|
| | |
| | { |
| |
|
| | |
| | { |
| | std::unique_ptr<MeshRenderPipelineD3D12> pipeline(new MeshRenderPipelineD3D12); |
| | NV_RETURN_ON_FAIL(pipeline->initialize(m_renderState, m_shadersPath, FRONT_WINDING_COUNTER_CLOCKWISE, m_shadowMapLinearSamplerIndex, m_shadowMap.get(), options.asyncComputeBenchmark)); |
| | m_meshPipeline = std::move(pipeline); |
| | } |
| | |
| | { |
| | std::unique_ptr<PointRenderPipelineD3D12> pipeline(new PointRenderPipelineD3D12); |
| | NV_RETURN_ON_FAIL(pipeline->initialize(m_renderState, m_shadersPath, m_shadowMapLinearSamplerIndex, m_shadowMap.get())); |
| | m_pointPipeline = std::move(pipeline); |
| | } |
| | |
| | { |
| | std::unique_ptr<FluidThicknessRenderPipelineD3D12> pipeline(new FluidThicknessRenderPipelineD3D12); |
| | NV_RETURN_ON_FAIL(pipeline->initialize(m_renderState, m_shadersPath, m_fluidThicknessRenderTarget.get())); |
| | m_fluidThicknessPipeline = std::move(pipeline); |
| | } |
| | |
| | { |
| | std::unique_ptr<FluidEllipsoidRenderPipelineD3D12> pipeline(new FluidEllipsoidRenderPipelineD3D12); |
| | NV_RETURN_ON_FAIL(pipeline->initialize(m_renderState, m_shadersPath, m_fluidPointRenderTarget.get())); |
| | m_fluidPointPipeline = std::move(pipeline); |
| | } |
| | |
| | { |
| | std::unique_ptr<FluidSmoothRenderPipelineD3D12> pipeline(new FluidSmoothRenderPipelineD3D12(m_fluidPointDepthSrvIndex)); |
| | NV_RETURN_ON_FAIL(pipeline->initialize(m_renderState, m_shadersPath, m_fluidSmoothRenderTarget.get())); |
| | m_fluidSmoothPipeline = std::move(pipeline); |
| | } |
| | |
| | { |
| | std::unique_ptr<FluidCompositeRenderPipelineD3D12> pipeline(new FluidCompositeRenderPipelineD3D12); |
| | NV_RETURN_ON_FAIL(pipeline->initialize(m_renderState, m_shadersPath)); |
| | m_fluidCompositePipeline = std::move(pipeline); |
| | } |
| | |
| | { |
| | std::unique_ptr<DiffusePointRenderPipelineD3D12> pipeline(new DiffusePointRenderPipelineD3D12); |
| | NV_RETURN_ON_FAIL(pipeline->initialize(m_renderState, m_shadersPath, m_linearSamplerIndex, m_shadowMap.get())); |
| | m_diffusePointPipeline = std::move(pipeline); |
| | } |
| | |
| | { |
| | std::unique_ptr<LineRenderPipelineD3D12> pipeline(new LineRenderPipelineD3D12); |
| | NV_RETURN_ON_FAIL(pipeline->initialize(m_renderState, m_shadersPath, m_shadowMap.get())); |
| | m_linePipeline = std::move(pipeline); |
| | } |
| | } |
| |
|
| | { |
| | |
| | uint32_t indices[] = { 0, 1, 2, 0, 2, 3 }; |
| | Vec3 pos[] = { { -1, -1, 0} , {1, -1, 0}, {1, 1, 0}, {-1, 1, 0} }; |
| | Vec2 uvs[] = { { 0, 0}, {1, 0}, {1, 1}, {0, 1} }; |
| |
|
| | MeshData mesh; |
| | mesh.init(); |
| |
|
| | mesh.indices = indices; |
| | mesh.positions = pos; |
| | mesh.texcoords = uvs; |
| | mesh.numFaces = _countof(indices) / 3; |
| | mesh.numVertices = _countof(pos); |
| |
|
| | m_screenQuadMesh = std::unique_ptr<FlexSample::RenderMesh>(m_meshRenderer->createMesh(mesh)); |
| | } |
| |
|
| | |
| | { |
| | m_graphicsCompleteEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); |
| | if (!m_graphicsCompleteEvent) |
| | { |
| | return E_FAIL; |
| | } |
| | NV_RETURN_ON_FAIL(device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_graphicsCompleteFence))); |
| | m_graphicsCompleteFenceValue = 1; |
| | } |
| |
|
| | { |
| | |
| |
|
| | |
| | const int queryCount = 2; |
| | D3D12_QUERY_HEAP_DESC queryHeapDesc = { D3D12_QUERY_HEAP_TYPE_TIMESTAMP, queryCount, 0 }; |
| | NV_RETURN_ON_FAIL(device->CreateQueryHeap(&queryHeapDesc, IID_PPV_ARGS(&m_queryHeap))); |
| |
|
| | D3D12_HEAP_PROPERTIES heapProps = |
| | { |
| | D3D12_HEAP_TYPE_READBACK, |
| | D3D12_CPU_PAGE_PROPERTY_UNKNOWN, |
| | D3D12_MEMORY_POOL_UNKNOWN, |
| | 0, |
| | 0 |
| | }; |
| |
|
| | D3D12_RESOURCE_DESC queryBufDesc = |
| | { |
| | D3D12_RESOURCE_DIMENSION_BUFFER, |
| | 0u, |
| | queryCount * sizeof(uint64_t), |
| | 1u, |
| | 1u, |
| | 1, |
| | DXGI_FORMAT_UNKNOWN, |
| | { 1u, 0u }, |
| | D3D12_TEXTURE_LAYOUT_ROW_MAJOR, |
| | D3D12_RESOURCE_FLAG_NONE |
| | }; |
| |
|
| | NV_RETURN_ON_FAIL(device->CreateCommittedResource( |
| | &heapProps, |
| | D3D12_HEAP_FLAG_NONE, |
| | &queryBufDesc, |
| | D3D12_RESOURCE_STATE_COPY_DEST, |
| | nullptr, |
| | IID_PPV_ARGS(&m_queryResults))); |
| |
|
| | D3D12_RESOURCE_DESC texDesc = {}; |
| | texDesc.MipLevels = 1u; |
| | texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; |
| | texDesc.Width = renderContext->m_winW; |
| | texDesc.Height = renderContext->m_winH; |
| | texDesc.Flags = D3D12_RESOURCE_FLAG_NONE; |
| | texDesc.DepthOrArraySize = 1u; |
| | texDesc.SampleDesc.Count = 1u; |
| | texDesc.SampleDesc.Quality = 0u; |
| | texDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; |
| |
|
| | |
| | m_footprint = {}; |
| | UINT64 uploadHeapSize = 0u; |
| | device->GetCopyableFootprints(&texDesc, 0u, 1u, 0u, &m_footprint, nullptr, nullptr, &uploadHeapSize); |
| |
|
| | D3D12_RESOURCE_DESC bufferDesc = texDesc; |
| | bufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; |
| | bufferDesc.Alignment = 0u; |
| | bufferDesc.Width = uploadHeapSize; |
| | bufferDesc.Height = 1u; |
| | bufferDesc.DepthOrArraySize = 1u; |
| | bufferDesc.MipLevels = 1; |
| | bufferDesc.Format = DXGI_FORMAT_UNKNOWN; |
| | bufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; |
| | bufferDesc.Flags = D3D12_RESOURCE_FLAG_NONE; |
| |
|
| | NV_RETURN_ON_FAIL(device->CreateCommittedResource( |
| | &heapProps, |
| | D3D12_HEAP_FLAG_NONE, |
| | &bufferDesc, |
| | D3D12_RESOURCE_STATE_COPY_DEST, |
| | nullptr, |
| | IID_PPV_ARGS(&m_bufferStage))); |
| | } |
| | return NV_OK; |
| | } |
| |
|
| | int DemoContextD3D12::_initFluidRenderTargets() |
| | { |
| | AppGraphCtxD3D12* renderContext = getRenderContext(); |
| | ID3D12Device* device = renderContext->m_device; |
| |
|
| | |
| | { |
| | { |
| | std::unique_ptr<NvCo::Dx12RenderTarget> target(new NvCo::Dx12RenderTarget); |
| | NvCo::Dx12RenderTarget::Desc desc; |
| | desc.init(renderContext->m_winW, renderContext->m_winH, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_TYPELESS); |
| | for (int i = 0; i != 4; i++) desc.m_targetClearColor[i] = 0; |
| |
|
| | NV_RETURN_ON_FAIL(target->init(renderContext, desc)); |
| |
|
| | target->setDebugName(L"Fluid Thickness"); |
| | m_fluidThicknessRenderTarget = std::move(target); |
| | } |
| | } |
| |
|
| | |
| | { |
| | { |
| | std::unique_ptr<NvCo::Dx12RenderTarget> target(new NvCo::Dx12RenderTarget); |
| | NvCo::Dx12RenderTarget::Desc desc; |
| | desc.init(renderContext->m_winW, renderContext->m_winH, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_TYPELESS); |
| | for (int i = 0; i != 4; i++) desc.m_targetClearColor[i] = 0; |
| |
|
| | NV_RETURN_ON_FAIL(target->init(renderContext, desc)); |
| |
|
| | target->setDebugName(L"Fluid Point"); |
| | m_fluidPointRenderTarget = std::move(target); |
| | } |
| | } |
| |
|
| | |
| | { |
| | std::unique_ptr<NvCo::Dx12RenderTarget> target(new NvCo::Dx12RenderTarget); |
| | NvCo::Dx12RenderTarget::Desc desc; |
| | desc.init(renderContext->m_winW, renderContext->m_winH, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN); |
| | for (int i = 0; i != 4; i++) desc.m_targetClearColor[i] = 0; |
| |
|
| | NV_RETURN_ON_FAIL(target->init(renderContext, desc)); |
| |
|
| | target->setDebugName(L"Fluid Smooth"); |
| | m_fluidSmoothRenderTarget = std::move(target); |
| | } |
| |
|
| | |
| | { |
| | std::unique_ptr<NvCo::Dx12RenderTarget> target(new NvCo::Dx12RenderTarget); |
| | NvCo::Dx12RenderTarget::Desc desc; |
| | Vec4 clearColor = { 1, 0, 1, 1 }; |
| | desc.m_targetClearColor = clearColor; |
| | desc.init(renderContext->m_winW, renderContext->m_winH, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN); |
| |
|
| | NV_RETURN_ON_FAIL(target->init(renderContext, desc)); |
| |
|
| | target->setDebugName(L"Fluid Resolved Target"); |
| | m_fluidResolvedTarget = std::move(target); |
| | } |
| |
|
| | |
| | { |
| | NvCo::Dx12DescriptorHeap& heap = *m_renderState.m_srvCbvUavDescriptorHeap; |
| | |
| | { |
| | m_fluidPointRenderTarget->createSrv(device, heap, NvCo::Dx12RenderTarget::BUFFER_TARGET, m_fluidPointDepthSrvIndex); |
| | m_fluidThicknessRenderTarget->createSrv(device, heap, NvCo::Dx12RenderTarget::BUFFER_TARGET, m_fluidPointDepthSrvIndex + 1); |
| | } |
| |
|
| | { |
| | |
| | |
| | |
| |
|
| | m_fluidSmoothRenderTarget->createSrv(device, heap, NvCo::Dx12RenderTarget::BUFFER_TARGET, m_fluidCompositeSrvBaseIndex + 0); |
| | m_fluidResolvedTarget->createSrv(device, heap, NvCo::Dx12RenderTarget::BUFFER_TARGET, m_fluidCompositeSrvBaseIndex + 1); |
| | m_shadowMap->createSrv(device, heap, NvCo::Dx12RenderTarget::BUFFER_DEPTH_STENCIL, m_fluidCompositeSrvBaseIndex + 2); |
| | } |
| | } |
| |
|
| | return NV_OK; |
| | } |
| |
|
| | void DemoContextD3D12::onSizeChanged(int width, int height, bool minimized) |
| | { |
| | |
| | m_fluidThicknessRenderTarget.reset(); |
| | m_fluidPointRenderTarget.reset(); |
| | m_fluidSmoothRenderTarget.reset(); |
| | m_fluidResolvedTarget.reset(); |
| |
|
| | AppGraphCtxUpdateSize(m_appGraphCtx, m_window, false, m_msaaSamples); |
| |
|
| | |
| | _initFluidRenderTargets(); |
| | } |
| |
|
| | void DemoContextD3D12::startFrame(FlexVec4 colorIn) |
| | { |
| | AppGraphCtxD3D12* renderContext = getRenderContext(); |
| |
|
| | |
| | m_renderStateManager->updateCompleted(); |
| |
|
| | AppGraphColor clearColor = { colorIn.x, colorIn.y, colorIn.z, colorIn.w }; |
| | AppGraphCtxFrameStart(cast_from_AppGraphCtxD3D12(renderContext), clearColor); |
| |
|
| | { |
| | MeshDrawParamsD3D& params = m_meshDrawParams; |
| | memset(¶ms, 0, sizeof(MeshDrawParamsD3D)); |
| | params.renderStage = MESH_DRAW_LIGHT; |
| | params.renderMode = MESH_RENDER_SOLID; |
| | params.cullMode = MESH_CULL_BACK; |
| | params.projection = XMMatrixIdentity(); |
| | params.view = XMMatrixIdentity(); |
| | params.model = DirectX::XMMatrixMultiply( |
| | DirectX::XMMatrixScaling(1.0f, 1.0f, 1.0f), |
| | DirectX::XMMatrixTranslation(0.0f, 0.0f, 0.0f) |
| | ); |
| | } |
| | } |
| |
|
| | void DemoContextD3D12::endFrame() |
| | { |
| | { |
| | ImguiGraphDescD3D12 desc; |
| | desc.device = m_renderContext->m_device; |
| | desc.commandList = m_renderContext->m_commandList; |
| | desc.winW = m_renderContext->m_winW; |
| | desc.winH = m_renderContext->m_winH; |
| |
|
| | imguiGraphUpdate((ImguiGraphDesc*)&desc); |
| | } |
| |
|
| | AppGraphCtxD3D12* renderContext = getRenderContext(); |
| |
|
| | nvidia::Common::Dx12Resource& backBuffer = renderContext->m_backBuffers[renderContext->m_renderTargetIndex]; |
| | if (renderContext->m_numMsaaSamples > 1) |
| | { |
| | |
| | nvidia::Common::Dx12Resource& renderTarget = *renderContext->m_renderTargets[renderContext->m_renderTargetIndex]; |
| | assert(&renderTarget != &backBuffer); |
| | |
| | { |
| | nvidia::Common::Dx12BarrierSubmitter submitter(renderContext->m_commandList); |
| | renderTarget.transition(D3D12_RESOURCE_STATE_RESOLVE_SOURCE, submitter); |
| | backBuffer.transition(D3D12_RESOURCE_STATE_RESOLVE_DEST, submitter); |
| | } |
| | |
| | renderContext->m_commandList->ResolveSubresource(backBuffer, 0, renderTarget, 0, renderContext->m_targetInfo.m_renderTargetFormats[0]); |
| | } |
| |
|
| | |
| | { |
| | { |
| | nvidia::Common::Dx12BarrierSubmitter submitter(renderContext->m_commandList); |
| | backBuffer.transition(D3D12_RESOURCE_STATE_COPY_SOURCE, submitter); |
| | } |
| |
|
| | D3D12_TEXTURE_COPY_LOCATION dstCopy = {}; |
| | D3D12_TEXTURE_COPY_LOCATION srcCopy = {}; |
| | dstCopy.pResource = m_bufferStage; |
| | dstCopy.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; |
| | dstCopy.PlacedFootprint = m_footprint; |
| | srcCopy.pResource = backBuffer; |
| | srcCopy.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; |
| | srcCopy.SubresourceIndex = 0u; |
| | renderContext->m_commandList->CopyTextureRegion(&dstCopy, 0, 0, 0, &srcCopy, nullptr); |
| | } |
| |
|
| | { |
| | nvidia::Common::Dx12BarrierSubmitter submitter(renderContext->m_commandList); |
| | backBuffer.transition(D3D12_RESOURCE_STATE_PRESENT, submitter); |
| | } |
| |
|
| | renderContext->m_commandList->Close(); |
| |
|
| | |
| | ID3D12CommandList* cmdLists[] = { renderContext->m_commandList }; |
| | renderContext->m_commandQueue->ExecuteCommandLists(1, cmdLists); |
| |
|
| | renderContext->m_commandListOpenCount = 0; |
| |
|
| | |
| | m_renderStateManager->onGpuWorkSubmitted(renderContext->m_commandQueue); |
| |
|
| | HANDLE completeEvent = m_graphicsCompleteEvent; |
| |
|
| | renderContext->m_commandQueue->Signal(m_graphicsCompleteFence, m_graphicsCompleteFenceValue); |
| | } |
| |
|
| | void DemoContextD3D12::getRenderDevice(void** device, void** context) |
| | { |
| | *device = m_renderContext->m_device; |
| | *context = m_renderContext->m_commandQueue; |
| | } |
| |
|
| | void DemoContextD3D12::startGpuWork() |
| | { |
| | AppGraphCtxBeginGpuWork(m_renderContext); |
| | } |
| |
|
| | void DemoContextD3D12::endGpuWork() |
| | { |
| | AppGraphCtxEndGpuWork(m_renderContext); |
| | } |
| |
|
| | void DemoContextD3D12::presentFrame(bool fullsync) |
| | { |
| | AppGraphCtxFramePresent(cast_from_AppGraphCtxD3D12(m_renderContext), fullsync); |
| | } |
| |
|
| | void DemoContextD3D12::readFrame(int* buffer, int width, int height) |
| | { |
| | AppGraphCtxD3D12* renderContext = getRenderContext(); |
| | |
| | AppGraphCtxWaitForGPU(renderContext); |
| |
|
| | int *pData; |
| | m_bufferStage->Map(0, nullptr, (void**)&pData); |
| | |
| | for (int i = 0; i < height; i++) |
| | { |
| | memcpy(buffer + (width * i), ((int *)pData) + (width * (height - i)), width * sizeof(int)); |
| | } |
| | m_bufferStage->Unmap(0, nullptr); |
| | } |
| |
|
| | void DemoContextD3D12::getViewRay(int x, int y, FlexVec3& origin, FlexVec3& dir) |
| | { |
| | |
| | AppGraphCtxD3D12* renderContext = getRenderContext(); |
| |
|
| | int width = renderContext->m_winW; |
| | int height = renderContext->m_winH; |
| |
|
| | XMVECTOR nearVector = XMVector3Unproject(XMVectorSet(float(x), float(height - y), 0.0f, 0.0f), 0.0f, 0.0f, (float)width, (float)height, 0.0f, 1.0f, (XMMATRIX)m_proj, XMMatrixIdentity(), (XMMATRIX)m_view); |
| | XMVECTOR farVector = XMVector3Unproject(XMVectorSet(float(x), float(height - y), 1.0f, 0.0f), 0.0f, 0.0f, (float)width, (float)height, 0.0f, 1.0f, (XMMATRIX)m_proj, XMMatrixIdentity(), (XMMATRIX)m_view); |
| |
|
| | origin = FlexVec3(XMVectorGetX(nearVector), XMVectorGetY(nearVector), XMVectorGetZ(nearVector)); |
| | XMVECTOR tmp = farVector - nearVector; |
| | dir = Normalize(FlexVec3(XMVectorGetX(tmp), XMVectorGetY(tmp), XMVectorGetZ(tmp))); |
| | } |
| |
|
| | void DemoContextD3D12::setView(Matrix44 view, Matrix44 projection) |
| | { |
| | Matrix44 vp = projection*view; |
| | MeshDrawParamsD3D& params = m_meshDrawParams; |
| |
|
| | params.model = XMMatrixIdentity(); |
| | params.view = (XMMATRIX)view; |
| | params.projection = (XMMATRIX)(RenderParamsUtilD3D::convertGLToD3DProjection(projection)); |
| |
|
| | m_view = view; |
| | m_proj = RenderParamsUtilD3D::convertGLToD3DProjection(projection); |
| | } |
| |
|
| | void DemoContextD3D12::renderEllipsoids(FluidRenderer* renderer, FluidRenderBuffers* buffersIn, int n, int offset, float radius, float screenWidth, float screenAspect, float fov, FlexVec3 lightPos, FlexVec3 lightTarget, Matrix44 lightTransform, ::ShadowMap* shadowMap, FlexVec4 color, float blur, float ior, bool debug) |
| | { |
| | FluidRenderBuffersD3D12& buffers = *reinterpret_cast<FluidRenderBuffersD3D12*>(buffersIn); |
| | if (n == 0) |
| | return; |
| |
|
| | typedef PointRenderAllocationD3D12 Alloc; |
| |
|
| | Alloc alloc; |
| | alloc.init(PRIMITIVE_POINT); |
| |
|
| | alloc.m_numPrimitives = n; |
| | alloc.m_numPositions = 0; |
| | alloc.m_offset = offset; |
| |
|
| | alloc.m_indexBufferView = buffers.m_indicesView; |
| | alloc.m_vertexBufferViews[Alloc::VERTEX_VIEW_DENSITY] = buffers.m_densitiesView; |
| | alloc.m_vertexBufferViews[Alloc::VERTEX_VIEW_POSITION] = buffers.m_positionsView; |
| | alloc.m_vertexBufferViews[Alloc::VERTEX_VIEW_ANISOTROPY1] = buffers.m_anisotropiesViewArr[0]; |
| | alloc.m_vertexBufferViews[Alloc::VERTEX_VIEW_ANISOTROPY2] = buffers.m_anisotropiesViewArr[1]; |
| | alloc.m_vertexBufferViews[Alloc::VERTEX_VIEW_ANISOTROPY3] = buffers.m_anisotropiesViewArr[2]; |
| |
|
| | AppGraphCtxD3D12* renderContext = getRenderContext(); |
| |
|
| | FluidDrawParamsD3D params; |
| |
|
| | params.renderMode = FLUID_RENDER_SOLID; |
| | params.cullMode = FLUID_CULL_NONE; |
| | params.model = XMMatrixIdentity(); |
| | params.view = (XMMATRIX&)m_view; |
| | params.projection = (XMMATRIX&)m_proj; |
| |
|
| | |
| | |
| | params.renderStage = FLUID_DRAW_LIGHT; |
| |
|
| | const float viewHeight = tanf(fov / 2.0f); |
| | params.invViewport = Hlsl::float3(1.0f / screenWidth, screenAspect / screenWidth, 1.0f); |
| | params.invProjection = Hlsl::float3(screenAspect * viewHeight, viewHeight, 1.0f); |
| |
|
| | |
| | const float thicknessScale = 4.0f; |
| | params.pointRadius = thicknessScale * radius; |
| |
|
| | params.debug = 0; |
| | params.shadowMap = nullptr; |
| |
|
| | { |
| | m_fluidThicknessRenderTarget->toWritable(renderContext); |
| | m_fluidThicknessRenderTarget->bindAndClear(renderContext); |
| |
|
| | m_meshRenderer->drawTransitory(alloc, sizeof(Alloc), m_fluidThicknessPipeline.get(), ¶ms); |
| |
|
| | m_fluidThicknessRenderTarget->toReadable(renderContext); |
| | } |
| |
|
| | { |
| | m_fluidPointRenderTarget->toWritable(renderContext); |
| | m_fluidPointRenderTarget->bindAndClear(renderContext); |
| |
|
| | |
| | m_meshRenderer->drawTransitory(alloc, sizeof(Alloc), m_fluidPointPipeline.get(), ¶ms); |
| |
|
| | m_fluidPointRenderTarget->toReadable(renderContext); |
| | } |
| |
|
| | |
| | |
| |
|
| | { |
| | m_fluidSmoothRenderTarget->toWritable(renderContext); |
| | m_fluidSmoothRenderTarget->bind(renderContext); |
| |
|
| | params.blurRadiusWorld = radius * 0.5f; |
| | params.blurScale = screenWidth / screenAspect * (1.0f / (tanf(fov * 0.5f))); |
| | params.invTexScale = Hlsl::float4(1.0f / screenAspect, 1.0f, 0.0f, 0.0f); |
| | params.blurFalloff = blur; |
| | params.debug = debug; |
| | params.m_sampleDescriptorBase = m_linearSamplerIndex; |
| |
|
| | m_meshRenderer->draw(m_screenQuadMesh.get(), m_fluidSmoothPipeline.get(), ¶ms); |
| |
|
| | m_fluidSmoothRenderTarget->toReadable(renderContext); |
| | } |
| |
|
| | |
| | ID3D12GraphicsCommandList* commandList = m_renderContext->m_commandList; |
| | { |
| | |
| | NvCo::Dx12ResourceBase* targetResource = m_renderContext->m_renderTargets[m_renderContext->m_renderTargetIndex]; |
| | NvCo::Dx12ResourceBase& fluidResolvedTarget = m_fluidResolvedTarget->getResource(NvCo::Dx12RenderTarget::BUFFER_TARGET); |
| |
|
| | if (m_renderContext->m_numMsaaSamples > 1) |
| | { |
| | |
| | |
| |
|
| | { |
| | NvCo::Dx12BarrierSubmitter submitter(commandList); |
| | targetResource->transition(D3D12_RESOURCE_STATE_RESOLVE_SOURCE, submitter); |
| | fluidResolvedTarget.transition(D3D12_RESOURCE_STATE_RESOLVE_DEST, submitter); |
| | } |
| | |
| | const DXGI_FORMAT format = fluidResolvedTarget.getResource()->GetDesc().Format; |
| | commandList->ResolveSubresource(fluidResolvedTarget, 0, *targetResource, 0, format); |
| | } |
| | else |
| | { |
| | { |
| | NvCo::Dx12BarrierSubmitter submitter(commandList); |
| | targetResource->transition(D3D12_RESOURCE_STATE_COPY_SOURCE, submitter); |
| | fluidResolvedTarget.transition(D3D12_RESOURCE_STATE_COPY_DEST, submitter); |
| | } |
| | commandList->CopyResource(fluidResolvedTarget, *targetResource); |
| | } |
| |
|
| | { |
| | NvCo::Dx12BarrierSubmitter submitter(commandList); |
| | targetResource->transition(D3D12_RESOURCE_STATE_RENDER_TARGET, submitter); |
| | fluidResolvedTarget.transition(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, submitter); |
| | } |
| | } |
| |
|
| | |
| | |
| |
|
| | { |
| | m_shadowMap->toReadable(renderContext); |
| |
|
| | AppGraphCtxPrepareRenderTarget(renderContext); |
| |
|
| | FlexVec4 aspectWork(1.0f / screenWidth, screenAspect / screenWidth, 0, 0); |
| | params.invTexScale = (Hlsl::float4&)aspectWork; |
| | FlexVec4 clipPosToEyeWork(tanf(fov*0.5f)*screenAspect, tanf(fov*0.5f), 0, 0); |
| | params.clipPosToEye = (Hlsl::float4&)clipPosToEyeWork; |
| | params.color = (Hlsl::float4&)color; |
| | params.ior = ior; |
| | params.spotMin = gSpotMin; |
| | params.spotMax = gSpotMax; |
| | params.debug = debug; |
| |
|
| | params.lightPos = (Hlsl::float3&)lightPos; |
| | FlexVec3 lightDirWork = -Normalize(lightTarget - lightPos); |
| | params.lightDir = (Hlsl::float3&)lightDirWork; |
| | Matrix44 lightTransformWork = RenderParamsUtilD3D::convertGLToD3DProjection(lightTransform); |
| | params.lightTransform = (XMMATRIX&)lightTransformWork; |
| |
|
| | params.m_srvDescriptorBase = m_fluidCompositeSrvBaseIndex; |
| | params.m_sampleDescriptorBase = m_linearSamplerIndex; |
| | params.shadowMap = (ShadowMapD3D*)m_currentShadowMap; |
| |
|
| | m_meshRenderer->draw(m_screenQuadMesh.get(), m_fluidCompositePipeline.get(), ¶ms); |
| | } |
| | } |
| |
|
| | void DemoContextD3D12::updateFluidRenderBuffers(FluidRenderBuffers* buffersIn, FlexVec4* particles, float* densities, FlexVec4* anisotropy1, FlexVec4* anisotropy2, FlexVec4* anisotropy3, int numParticles, int* indices, int numIndices) |
| | { |
| | FluidRenderBuffersD3D12& buffers = *reinterpret_cast<FluidRenderBuffersD3D12*>(buffersIn); |
| |
|
| | typedef PointRenderAllocationD3D12 Alloc; |
| | Alloc alloc; |
| |
|
| | PointData pointData; |
| |
|
| | pointData.positions = (const Vec4*)particles; |
| | pointData.density = densities; |
| | pointData.phase = nullptr; |
| | pointData.indices = (uint32_t*)indices; |
| | pointData.numIndices = numIndices; |
| | pointData.numPoints = numParticles; |
| | pointData.anisotropy[0] = (const Vec4*)anisotropy1; |
| | pointData.anisotropy[1] = (const Vec4*)anisotropy2; |
| | pointData.anisotropy[2] = (const Vec4*)anisotropy3; |
| |
|
| | m_meshRenderer->allocateTransitory(pointData, alloc, sizeof(alloc)); |
| | |
| | buffers.m_positionsView = alloc.m_vertexBufferViews[Alloc::VERTEX_VIEW_POSITION]; |
| | buffers.m_densitiesView = alloc.m_vertexBufferViews[Alloc::VERTEX_VIEW_DENSITY]; |
| | |
| | buffers.m_anisotropiesViewArr[0] = alloc.m_vertexBufferViews[Alloc::VERTEX_VIEW_ANISOTROPY1]; |
| | buffers.m_anisotropiesViewArr[1] = alloc.m_vertexBufferViews[Alloc::VERTEX_VIEW_ANISOTROPY2]; |
| | buffers.m_anisotropiesViewArr[2] = alloc.m_vertexBufferViews[Alloc::VERTEX_VIEW_ANISOTROPY3]; |
| | |
| | buffers.m_indicesView = alloc.m_indexBufferView; |
| |
|
| | buffers.m_numParticles = numIndices; |
| | } |
| |
|
| | void DemoContextD3D12::shadowBegin(::ShadowMap* map) |
| | { |
| | assert(map); |
| | assert(m_targetShadowMap == nullptr); |
| |
|
| | AppGraphCtxD3D12* renderContext = getRenderContext(); |
| | NvCo::Dx12RenderTarget* shadowMap = reinterpret_cast<NvCo::Dx12RenderTarget*>(map); |
| |
|
| | shadowMap->toWritable(renderContext); |
| | shadowMap->bindAndClear(renderContext); |
| |
|
| | m_targetShadowMap = shadowMap; |
| |
|
| | m_meshDrawParams.renderStage = MESH_DRAW_SHADOW; |
| | } |
| |
|
| | void DemoContextD3D12::shadowEnd() |
| | { |
| | AppGraphCtxD3D12* renderContext = getRenderContext(); |
| | NvCo::Dx12RenderTarget* shadowMap = m_targetShadowMap; |
| | shadowMap->toReadable(renderContext); |
| | m_targetShadowMap = nullptr; |
| |
|
| | |
| | AppGraphCtxPrepareRenderTarget(renderContext); |
| |
|
| | m_meshDrawParams.renderStage = MESH_DRAW_NULL; |
| | } |
| |
|
| | void DemoContextD3D12::drawMesh(const Mesh* m, FlexVec3 color) |
| | { |
| | MeshDrawParamsD3D& params = m_meshDrawParams; |
| |
|
| | if (m) |
| | { |
| | MeshData meshData; |
| |
|
| | meshData.positions = (Vec3*)&m->m_positions[0]; |
| | meshData.normals = (Vec3*)&m->m_normals[0]; |
| | meshData.colors = nullptr; |
| | meshData.texcoords = nullptr; |
| | meshData.indices = (uint32_t*)&m->m_indices[0]; |
| | meshData.numFaces = m->GetNumFaces(); |
| | meshData.numVertices = m->GetNumVertices(); |
| |
|
| | params.colorArray = 0; |
| | if (m->m_colours.size()) |
| | { |
| | params.colorArray = 1; |
| | meshData.colors = (Vec4*)&m->m_colours[0]; |
| | } |
| |
|
| | params.color = Hlsl::float4(color.x, color.y, color.z, 1); |
| | params.secondaryColor = params.color; |
| | params.objectTransform = (Hlsl::float4x4&)Matrix44::kIdentity; |
| | params.shadowMap = (ShadowMapD3D*)m_currentShadowMap; |
| |
|
| | m_meshRenderer->drawImmediate(meshData, m_meshPipeline.get(), ¶ms); |
| |
|
| | if (m->m_colours.size()) |
| | { |
| | params.colorArray = 0; |
| | } |
| | } |
| | } |
| |
|
| | void DemoContextD3D12::drawCloth(const FlexVec4* positions, const FlexVec4* normals, const float* uvs, const int* indices, int numTris, int numPositions, int colorIndex, float expand, bool twosided, bool smooth) |
| | { |
| | if (!numTris) |
| | return; |
| |
|
| | MeshData2 meshData; |
| |
|
| | meshData.positions = (const Vec4*)positions; |
| | meshData.normals = (const Vec4*)normals; |
| | meshData.texcoords = nullptr; |
| | meshData.colors = nullptr; |
| | meshData.numFaces = numTris; |
| | meshData.indices = (const uint32_t*)indices; |
| | meshData.numVertices = numPositions; |
| |
|
| | if (twosided) |
| | SetCullMode(false); |
| |
|
| | MeshDrawParamsD3D& params = m_meshDrawParams; |
| |
|
| | params.bias = 0.0f; |
| | params.expand = expand; |
| |
|
| | params.color = (Hlsl::float4&)(g_colors[colorIndex + 1] * 1.5f); |
| | params.secondaryColor = (Hlsl::float4&)(g_colors[colorIndex] * 1.5f); |
| | params.objectTransform = (Hlsl::float4x4&)Matrix44::kIdentity; |
| | params.shadowMap = (ShadowMapD3D*)m_currentShadowMap; |
| |
|
| | m_meshRenderer->drawImmediate(meshData, m_meshPipeline.get(), ¶ms); |
| |
|
| | if (twosided) |
| | SetCullMode(true); |
| |
|
| | params.bias = gShadowBias; |
| | params.expand = 0.0f; |
| | } |
| |
|
| | void DemoContextD3D12::drawRope(FlexVec4* positions, int* indices, int numIndices, float radius, int color) |
| | { |
| | if (numIndices < 2) |
| | return; |
| |
|
| | std::vector<FlexVec3> vertices; |
| | std::vector<FlexVec3> normals; |
| | std::vector<int> triangles; |
| |
|
| | |
| | std::vector<FlexVec3> curve(numIndices); |
| | for (int i = 0; i < numIndices; ++i) |
| | { |
| | curve[i] = FlexVec3(positions[indices[i]]); |
| | } |
| |
|
| | const int resolution = 8; |
| | const int smoothing = 3; |
| |
|
| | vertices.reserve(resolution*numIndices*smoothing); |
| | normals.reserve(resolution*numIndices*smoothing); |
| | triangles.reserve(numIndices*resolution * 6 * smoothing); |
| |
|
| | Extrude(&curve[0], int(curve.size()), vertices, normals, triangles, radius, resolution, smoothing); |
| |
|
| | SetCullMode(false); |
| |
|
| | MeshDrawParamsD3D& params = m_meshDrawParams; |
| |
|
| | params.color = (Hlsl::float4&)(g_colors[color % 8] * 1.5f); |
| | params.secondaryColor = (Hlsl::float4&)(g_colors[color % 8] * 1.5f); |
| | params.shadowMap = (ShadowMapD3D*)m_currentShadowMap; |
| |
|
| | MeshData meshData; |
| |
|
| | meshData.positions = (const Vec3*)&vertices[0]; |
| | meshData.normals = (const Vec3*)&normals[0]; |
| | meshData.texcoords = nullptr; |
| | meshData.colors = nullptr; |
| | meshData.indices = (const uint32_t*)&triangles[0]; |
| | meshData.numFaces = int(triangles.size()) / 3; |
| | meshData.numVertices = int(vertices.size()); |
| |
|
| | m_meshRenderer->drawImmediate(meshData, m_meshPipeline.get(), ¶ms); |
| |
|
| | SetCullMode(true); |
| | } |
| |
|
| | void DemoContextD3D12::drawPlane(const FlexVec4& p, bool color) |
| | { |
| | std::vector<FlexVec3> vertices; |
| | std::vector<FlexVec3> normals; |
| | std::vector<int> indices; |
| |
|
| | FlexVec3 u, v; |
| | BasisFromVector(FlexVec3(p.x, p.y, p.z), &u, &v); |
| |
|
| | FlexVec3 c = FlexVec3(p.x, p.y, p.z)*-p.w; |
| |
|
| | MeshDrawParamsD3D& params = m_meshDrawParams; |
| |
|
| | params.shadowMap = (ShadowMapD3D*)m_currentShadowMap; |
| |
|
| | if (color) |
| | params.color = (Hlsl::float4&)(p * 0.5f + FlexVec4(0.5f, 0.5f, 0.5f, 0.5f)); |
| |
|
| | const float kSize = 200.0f; |
| | const int kGrid = 3; |
| |
|
| | |
| | for (int x = -kGrid; x <= kGrid; ++x) |
| | { |
| | for (int y = -kGrid; y <= kGrid; ++y) |
| | { |
| | FlexVec3 coff = c + u*float(x)*kSize*2.0f + v*float(y)*kSize*2.0f; |
| |
|
| | int indexStart = int(vertices.size()); |
| |
|
| | vertices.push_back(FlexVec3(coff + u*kSize + v*kSize)); |
| | vertices.push_back(FlexVec3(coff - u*kSize + v*kSize)); |
| | vertices.push_back(FlexVec3(coff - u*kSize - v*kSize)); |
| | vertices.push_back(FlexVec3(coff + u*kSize - v*kSize)); |
| |
|
| | normals.push_back(FlexVec3(p.x, p.y, p.z)); |
| | normals.push_back(FlexVec3(p.x, p.y, p.z)); |
| | normals.push_back(FlexVec3(p.x, p.y, p.z)); |
| | normals.push_back(FlexVec3(p.x, p.y, p.z)); |
| |
|
| |
|
| | indices.push_back(indexStart + 0); |
| | indices.push_back(indexStart + 1); |
| | indices.push_back(indexStart + 2); |
| |
|
| | indices.push_back(indexStart + 2); |
| | indices.push_back(indexStart + 3); |
| | indices.push_back(indexStart + 0); |
| | } |
| | } |
| |
|
| | MeshData meshData; |
| | meshData.texcoords = nullptr; |
| | meshData.colors = nullptr; |
| | meshData.positions = (Vec3*)&vertices[0]; |
| | meshData.normals = (Vec3*)&normals[0]; |
| | meshData.indices = (uint32_t*)&indices[0]; |
| | meshData.numFaces = int(indices.size() / 3); |
| | meshData.numVertices = int(vertices.size()); |
| |
|
| | m_meshRenderer->drawImmediate(meshData, m_meshPipeline.get(), ¶ms); |
| | } |
| |
|
| | void DemoContextD3D12::drawPlanes(FlexVec4* planes, int n, float bias) |
| | { |
| | MeshDrawParamsD3D& params = m_meshDrawParams; |
| |
|
| | params.color = (Hlsl::float4&)FlexVec4(0.9f, 0.9f, 0.9f, 1.0f); |
| |
|
| | params.bias = 0.0f; |
| | params.grid = 1; |
| | params.expand = 0; |
| |
|
| | for (int i = 0; i < n; ++i) |
| | { |
| | FlexVec4 p = planes[i]; |
| | p.w -= bias; |
| |
|
| | drawPlane(p, false); |
| | } |
| |
|
| | params.grid = 0; |
| | params.bias = gShadowBias; |
| | } |
| |
|
| | void DemoContextD3D12::drawPoints(FluidRenderBuffers* buffersIn, int n, int offset, float radius, float screenWidth, float screenAspect, float fov, FlexVec3 lightPos, FlexVec3 lightTarget, Matrix44 lightTransform, ::ShadowMap* shadowTex, bool showDensity) |
| | { |
| | FluidRenderBuffersD3D12* buffers = reinterpret_cast<FluidRenderBuffersD3D12*>(buffersIn); |
| | |
| |
|
| | if (n == 0) |
| | return; |
| |
|
| | PointRenderAllocationD3D12 pointAlloc; |
| | pointAlloc.init(PRIMITIVE_POINT); |
| | pointAlloc.m_vertexBufferViews[PointRenderAllocationD3D12::VERTEX_VIEW_POSITION] = buffers->m_positionsView; |
| | |
| | pointAlloc.m_vertexBufferViews[PointRenderAllocationD3D12::VERTEX_VIEW_DENSITY] = buffers->m_densitiesView; |
| | pointAlloc.m_vertexBufferViews[PointRenderAllocationD3D12::VERTEX_VIEW_PHASE] = buffers->m_densitiesView; |
| | pointAlloc.m_indexBufferView = buffers->m_indicesView; |
| |
|
| | pointAlloc.m_numPrimitives = n; |
| | pointAlloc.m_numPositions = 0; |
| | pointAlloc.m_offset = offset; |
| | |
| | PointDrawParamsD3D params; |
| |
|
| | params.renderMode = POINT_RENDER_SOLID; |
| | params.cullMode = POINT_CULL_BACK; |
| | params.model = XMMatrixIdentity(); |
| | params.view = (XMMATRIX&)m_view; |
| | params.projection = (XMMATRIX&)m_proj; |
| |
|
| | params.pointRadius = radius; |
| | params.pointScale = screenWidth / screenAspect * (1.0f / (tanf(fov * 0.5f))); |
| | params.spotMin = gSpotMin; |
| | params.spotMax = gSpotMax; |
| |
|
| | int mode = 0; |
| | if (showDensity) |
| | mode = 1; |
| | if (shadowTex == 0) |
| | mode = 2; |
| | params.mode = mode; |
| |
|
| | for (int i = 0; i < 8; i++) |
| | params.colors[i] = *((Hlsl::float4*)&g_colors[i].r); |
| |
|
| | |
| | ShadowParamsD3D shadow; |
| | RenderParamsUtilD3D::calcShadowParams(lightPos, lightTarget, lightTransform, gShadowBias, &shadow); |
| | params.lightTransform = shadow.lightTransform; |
| | params.lightDir = shadow.lightDir; |
| | params.lightPos = shadow.lightPos; |
| | memcpy(params.shadowTaps, shadow.shadowTaps, sizeof(shadow.shadowTaps)); |
| |
|
| | if (m_meshDrawParams.renderStage == MESH_DRAW_SHADOW) |
| | { |
| | params.renderStage = POINT_DRAW_SHADOW; |
| | params.mode = 2; |
| | } |
| | else |
| | params.renderStage = POINT_DRAW_LIGHT; |
| |
|
| | params.shadowMap = (ShadowMapD3D*)m_currentShadowMap; |
| |
|
| | m_meshRenderer->drawTransitory(pointAlloc, sizeof(pointAlloc), m_pointPipeline.get(), ¶ms); |
| | } |
| |
|
| | void DemoContextD3D12::graphicsTimerBegin() |
| | { |
| | ID3D12GraphicsCommandList* commandList = m_renderContext->m_commandList; |
| |
|
| | commandList->EndQuery(m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, 0); |
| | } |
| |
|
| | void DemoContextD3D12::graphicsTimerEnd() |
| | { |
| | ID3D12GraphicsCommandList* commandList = m_renderContext->m_commandList; |
| |
|
| | commandList->EndQuery(m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, 1); |
| | commandList->ResolveQueryData(m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, 0, 2, m_queryResults, 0); |
| | } |
| |
|
| | float DemoContextD3D12::rendererGetDeviceTimestamps(unsigned long long* begin, unsigned long long* end, unsigned long long* freq) |
| | { |
| | AppGraphCtxD3D12* renderContext = getRenderContext(); |
| | ID3D12CommandQueue* commandQueue = m_renderContext->m_commandQueue; |
| |
|
| | AppGraphCtxWaitForGPU(renderContext); |
| |
|
| | |
| | static uint64_t frequency = 0; |
| |
|
| | if (frequency == 0) |
| | { |
| | commandQueue->GetTimestampFrequency(&frequency); |
| | } |
| |
|
| | |
| | uint64_t* times; |
| | D3D12_RANGE readRange = { 0, 2 }; |
| | m_queryResults->Map(0, &readRange, (void**)×); |
| | uint64_t renderBegin = times[0]; |
| | uint64_t renderEnd = times[1]; |
| | D3D12_RANGE writtenRange = { 0, 0 }; |
| | m_queryResults->Unmap(0, &writtenRange); |
| |
|
| | double renderTime = double(renderEnd - renderBegin) / double(frequency); |
| |
|
| | if (begin) *begin = renderBegin; |
| | if (end) *end = renderEnd; |
| | if (freq) *freq = frequency; |
| |
|
| | return float(renderTime); |
| | } |
| |
|
| | void DemoContextD3D12::bindSolidShader(FlexVec3 lightPos, FlexVec3 lightTarget, Matrix44 lightTransform, ::ShadowMap* shadowMap, float bias, FlexVec4 fogColor) |
| | { |
| | MeshDrawParamsD3D& params = m_meshDrawParams; |
| |
|
| | params.renderStage = MESH_DRAW_LIGHT; |
| |
|
| | params.grid = 0; |
| | params.spotMin = gSpotMin; |
| | params.spotMax = gSpotMax; |
| | params.fogColor = (Hlsl::float4&)fogColor; |
| |
|
| | params.objectTransform = (Hlsl::float4x4&)Matrix44::kIdentity; |
| |
|
| | ShadowParamsD3D shadow; |
| | RenderParamsUtilD3D::calcShadowParams(lightPos, lightTarget, lightTransform, gShadowBias, &shadow); |
| | params.lightTransform = shadow.lightTransform; |
| | params.lightDir = shadow.lightDir; |
| | params.lightPos = shadow.lightPos; |
| | params.bias = shadow.bias; |
| | memcpy(params.shadowTaps, shadow.shadowTaps, sizeof(shadow.shadowTaps)); |
| |
|
| | m_currentShadowMap = (NvCo::Dx12RenderTarget*)shadowMap; |
| | } |
| |
|
| | void DemoContextD3D12::drawGpuMesh(GpuMesh* m, const Matrix44& xform, const FlexVec3& color) |
| | { |
| | if (m) |
| | { |
| | MeshDrawParamsD3D params(m_meshDrawParams); |
| |
|
| | params.color = (Hlsl::float4&)color; |
| | params.secondaryColor = (Hlsl::float4&)color; |
| | params.objectTransform = (Hlsl::float4x4&)xform; |
| | params.shadowMap = (ShadowMapD3D*)m_currentShadowMap; |
| |
|
| | RenderMesh* renderMesh = (RenderMesh*)m; |
| |
|
| | m_meshRenderer->draw(renderMesh, m_meshPipeline.get(), ¶ms); |
| | } |
| | } |
| |
|
| | void DemoContextD3D12::drawGpuMeshInstances(GpuMesh* m, const Matrix44* xforms, int n, const FlexVec3& color) |
| | { |
| | if (m) |
| | { |
| | MeshDrawParamsD3D& contextParams = m_meshDrawParams; |
| |
|
| | contextParams.color = (Hlsl::float4&)color; |
| | contextParams.secondaryColor = (Hlsl::float4&)color; |
| | contextParams.shadowMap = (ShadowMapD3D*)m_currentShadowMap; |
| |
|
| | |
| | MeshDrawParamsD3D params(contextParams); |
| |
|
| | for (int i = 0; i < n; ++i) |
| | { |
| | params.objectTransform = (Hlsl::float4x4&)xforms[i]; |
| | RenderMesh* renderMesh = (RenderMesh*)m; |
| | m_meshRenderer->draw(renderMesh, m_meshPipeline.get(), ¶ms); |
| | } |
| | } |
| | } |
| |
|
| | void DemoContextD3D12::drawDiffuse(FluidRenderer* render, const DiffuseRenderBuffers* buffersIn, int n, float radius, float screenWidth, float screenAspect, float fov, FlexVec4 color, FlexVec3 lightPos, FlexVec3 lightTarget, Matrix44 lightTransform, ShadowMap* shadowMap, float motionBlur, float inscatter, float outscatter, bool shadowEnabled, bool front) |
| | { |
| | const DiffuseRenderBuffersD3D12& buffers = *reinterpret_cast<const DiffuseRenderBuffersD3D12*>(buffersIn); |
| | if (n == 0) |
| | return; |
| |
|
| | typedef PointRenderAllocationD3D12 Alloc; |
| | Alloc alloc; |
| | alloc.init(PRIMITIVE_POINT); |
| |
|
| | alloc.m_numPrimitives = n; |
| | alloc.m_numPositions = 0; |
| | alloc.m_offset = 0; |
| |
|
| | alloc.m_indexBufferView = buffers.m_indicesView; |
| | alloc.m_vertexBufferViews[Alloc::VERTEX_VIEW_POSITION] = buffers.m_positionsView; |
| | alloc.m_vertexBufferViews[Alloc::VERTEX_VIEW_ANISOTROPY1] = buffers.m_velocitiesView; |
| |
|
| | DiffuseDrawParamsD3D params; |
| |
|
| | params.model = XMMatrixIdentity(); |
| | params.view = (const XMMATRIX&)m_view; |
| | params.projection = (const XMMATRIX&)m_proj; |
| | params.diffuseRadius = screenWidth / screenAspect * (1.0f / (tanf(fov * 0.5f))); |
| | params.diffuseScale = radius; |
| | params.spotMin = gSpotMin; |
| | params.spotMax = gSpotMax; |
| | params.color = Hlsl::float4(1.0f, 1.0f, 1.0f, 1.0f); |
| | params.motionScale = motionBlur; |
| |
|
| | |
| | ShadowParamsD3D shadow; |
| | RenderParamsUtilD3D::calcShadowParams(lightPos, lightTarget, lightTransform, gShadowBias, &shadow); |
| | params.lightTransform = shadow.lightTransform; |
| | params.lightDir = shadow.lightDir; |
| | params.lightPos = shadow.lightPos; |
| | params.shadowMap = (ShadowMapD3D*)m_currentShadowMap; |
| |
|
| | memcpy(params.shadowTaps, shadow.shadowTaps, sizeof(shadow.shadowTaps)); |
| |
|
| | m_meshRenderer->drawTransitory(alloc, sizeof(alloc), m_diffusePointPipeline.get(), ¶ms); |
| | } |
| |
|
| | void DemoContextD3D12::beginLines() |
| | { |
| | assert(!m_inLineDraw); |
| | m_inLineDraw = true; |
| | m_debugLineVertices.clear(); |
| | } |
| |
|
| | void DemoContextD3D12::drawLine(const Vec3& p, const Vec3& q, const Vec4& color) |
| | { |
| | assert(m_inLineDraw); |
| |
|
| | if (m_debugLineVertices.size() + 2 > MAX_DEBUG_LINE_SIZE) |
| | { |
| | _flushDebugLines(); |
| | } |
| |
|
| | LineData::Vertex dst[2]; |
| | dst[0].position = (const Vec3&)p; |
| | dst[0].color = (const Vec4&)color; |
| | dst[1].position = (const Vec3&)q; |
| | dst[1].color = (const Vec4&)color; |
| |
|
| | m_debugLineVertices.push_back(dst[0]); |
| | m_debugLineVertices.push_back(dst[1]); |
| | } |
| |
|
| | void DemoContextD3D12::_flushDebugLines() |
| | { |
| | assert(m_inLineDraw); |
| |
|
| | if (m_debugLineVertices.size() > 0) |
| | { |
| | LineDrawParams params; |
| |
|
| | const Matrix44 modelWorldProjection = ((Matrix44&)(m_meshDrawParams.projection)) * ((Matrix44&)(m_meshDrawParams.view)); |
| | |
| | params.m_modelWorldProjection = (const Hlsl::float4x4&)modelWorldProjection; |
| | params.m_drawStage = (m_targetShadowMap) ? LINE_DRAW_SHADOW : LINE_DRAW_NORMAL; |
| |
|
| | LineData lineData; |
| | lineData.init(); |
| | lineData.vertices = &m_debugLineVertices.front(); |
| | lineData.numVertices = m_debugLineVertices.size(); |
| | lineData.numLines = lineData.numVertices / 2; |
| |
|
| | m_meshRenderer->drawImmediate(lineData, m_linePipeline.get(), ¶ms); |
| | |
| | m_debugLineVertices.clear(); |
| | } |
| | } |
| |
|
| | void DemoContextD3D12::endLines() |
| | { |
| | _flushDebugLines(); |
| | |
| | m_inLineDraw = false; |
| | } |
| |
|
| | void DemoContextD3D12::flushGraphicsAndWait() |
| | { |
| | AppGraphCtxWaitForGPU(getRenderContext()); |
| | } |
| |
|
| | FluidRenderer* DemoContextD3D12::createFluidRenderer(uint32_t width, uint32_t height) |
| | { |
| | |
| | return (FluidRenderer*)this; |
| | } |
| |
|
| | void DemoContextD3D12::destroyFluidRenderer(FluidRenderer* renderer) |
| | { |
| | |
| | } |
| |
|
| | FluidRenderBuffers* DemoContextD3D12::createFluidRenderBuffers(int numParticles, bool enableInterop) |
| | { |
| | return reinterpret_cast<FluidRenderBuffers*>(new FluidRenderBuffersD3D12(numParticles)); |
| | } |
| |
|
| | void DemoContextD3D12::updateFluidRenderBuffers(FluidRenderBuffers* buffers, NvFlexSolver* flex, bool anisotropy, bool density) |
| | { |
| | printf("Not implemented"); |
| | assert(0); |
| | } |
| |
|
| | void DemoContextD3D12::destroyFluidRenderBuffers(FluidRenderBuffers* buffers) |
| | { |
| | delete reinterpret_cast<FluidRenderBuffersD3D12*>(buffers); |
| | } |
| |
|
| | ShadowMap* DemoContextD3D12::shadowCreate() |
| | { |
| | |
| | return (::ShadowMap*)m_shadowMap.get(); |
| | } |
| |
|
| | void DemoContextD3D12::shadowDestroy(ShadowMap* map) |
| | { |
| | assert(map); |
| | assert(m_shadowMap.get() == (NvCo::Dx12RenderTarget*)map); |
| | } |
| |
|
| | void DemoContextD3D12::unbindSolidShader() |
| | { |
| | m_meshDrawParams.renderStage = MESH_DRAW_NULL; |
| |
|
| | |
| | |
| | } |
| |
|
| | GpuMesh* DemoContextD3D12::createGpuMesh(const Mesh* m) |
| | { |
| | if (m) |
| | { |
| | return (GpuMesh*)MeshUtil::createRenderMesh(m_meshRenderer.get(), *m); |
| | } |
| | return nullptr; |
| | } |
| |
|
| | void DemoContextD3D12::destroyGpuMesh(GpuMesh* m) |
| | { |
| | delete reinterpret_cast<RenderMesh*>(m); |
| | } |
| |
|
| | DiffuseRenderBuffers* DemoContextD3D12::createDiffuseRenderBuffers(int numDiffuseParticles, bool& enableInterop) |
| | { |
| | return reinterpret_cast<DiffuseRenderBuffers*>(new DiffuseRenderBuffersD3D12(numDiffuseParticles)); |
| | } |
| |
|
| | void DemoContextD3D12::destroyDiffuseRenderBuffers(DiffuseRenderBuffers* buffers) |
| | { |
| | delete reinterpret_cast<DiffuseRenderBuffersD3D12*>(buffers); |
| | } |
| |
|
| | int DemoContextD3D12::getNumDiffuseRenderParticles(DiffuseRenderBuffers* buffers) |
| | { |
| | return reinterpret_cast<DiffuseRenderBuffersD3D12*>(buffers)->m_numParticles; |
| | } |
| |
|
| | void DemoContextD3D12::updateDiffuseRenderBuffers(DiffuseRenderBuffers* buffersIn, Vec4* diffusePositions, Vec4* diffuseVelocities, int numDiffuseParticles) |
| | { |
| | DiffuseRenderBuffersD3D12& buffers = *reinterpret_cast<DiffuseRenderBuffersD3D12*>(buffersIn); |
| |
|
| | typedef PointRenderAllocationD3D12 Alloc; |
| |
|
| | Alloc alloc; |
| |
|
| | PointData pointData; |
| | pointData.init(); |
| | pointData.numIndices = numDiffuseParticles; |
| | pointData.positions = (Vec4*)diffusePositions; |
| | pointData.anisotropy[0] = (Vec4*)diffuseVelocities; |
| | pointData.numPoints = buffers.m_numParticles; |
| |
|
| | m_meshRenderer->allocateTransitory(pointData, alloc, sizeof(alloc)); |
| |
|
| | buffers.m_indicesView = alloc.m_indexBufferView; |
| | buffers.m_positionsView = alloc.m_vertexBufferViews[Alloc::VERTEX_VIEW_POSITION]; |
| | buffers.m_velocitiesView = alloc.m_vertexBufferViews[Alloc::VERTEX_VIEW_ANISOTROPY1]; |
| |
|
| | buffers.m_numParticles = numDiffuseParticles; |
| | } |
| |
|
| | void DemoContextD3D12::updateDiffuseRenderBuffers(DiffuseRenderBuffers* buffers, NvFlexSolver* solver) |
| | { |
| | printf("Not implemented"); |
| | assert(0); |
| | } |
| |
|
| | void* DemoContextD3D12::getGraphicsCommandQueue() |
| | { |
| | return m_renderContext->m_commandQueue; |
| | } |
| |
|
| | void DemoContextD3D12::setFillMode(bool wire) |
| | { |
| | m_meshDrawParams.renderMode = wire ? MESH_RENDER_WIREFRAME : MESH_RENDER_SOLID; |
| | } |
| |
|
| | void DemoContextD3D12::setCullMode(bool enabled) |
| | { |
| | m_meshDrawParams.cullMode = enabled ? MESH_CULL_BACK : MESH_CULL_NONE; |
| | } |
| |
|
| | void DemoContextD3D12::drawImguiGraph() |
| | { |
| | imguiGraphDraw(); |
| | } |
| |
|
| | } |
| |
|