Пример #1
0
DWORD __stdcall GameThreadMain(void* args)
{
	HWND hWnd = (HWND) args;

	Render::Init();
	SwapChain swapChain;
	swapChain.Create(hWnd, OUTPUT_SIZE_X, OUTPUT_SIZE_Y);

	Core::Load();
	Core::SetSwapChain(&swapChain);

	for (;;)
	{
		Core::Update();
		swapChain.Present();
	}
	return 0;
}
Пример #2
0
 void Queue::present(
     Semaphore& signalSemaphore,
     SwapChain& swapChain,
     unsigned int chainIndex)
 {
     auto transitionCmd = m_device.createCommandList();
     transitionCmd.transition(swapChain.renderTarget(chainIndex), ResourceState::Present);
     submit(transitionCmd);
     m_impl->present(signalSemaphore, swapChain, chainIndex);
 }
// ---------------------------------------------------------------------------------------------------------
LVEDRENDERINGENGINE_API void __stdcall LvEd_End()
{
    RenderContext* rc = RenderContext::Inst();
    RenderSurface* surface = s_engineData->pRenderSurface;

    s_engineData->basicRenderer->End();    
    LineRenderer::Inst()->RenderAll(rc);
    ErrorHandler::ClearError();    
    LvEdFonts::FontRenderer::Inst()->FlushPrintRequests( rc );
    
    if(surface->GetType() == RenderSurface::kSwapChain)
    {        
        RenderWorldAxis();
        SwapChain* swapchain = static_cast<SwapChain*>(surface);
        HRESULT hr = swapchain->GetDXGISwapChain()->Present(0,0);
        Logger::IsFailureLog(hr, L"presenting swapchain");
    }

    s_engineData->renderableSorter.ClearLists();    
    s_engineData->pRenderSurface = NULL;    
    RenderContext::Inst()->LightEnvDirty = false; 
}
Пример #4
0
    void mainLoop(double deltaTime) override
    {
        auto cmd        = device.graphicsCommandList();
        auto backbuffer = swapChain.backbuffer();

        cmd.imguiBeginFrame(swapChain, deltaTime);
        ImGui::ShowTestWindow();

        cmd.clearRTV(backbuffer, float4(0, 0, .25f, 1));

        cmd.setRenderTargets({backbuffer});
        cmd.bind(hello);
        cube.setForRendering(cmd);

        float objectPhase = frac(time.secondsF() / ObjectPeriod) * 2 * Pi;
        float cameraPhase = frac(time.secondsF() / CameraPeriod) * 2 * Pi;

        Hello::Constants c;

        float3 cameraPos;
        cameraPos.x = cos(cameraPhase) * CameraDistance;
        cameraPos.z = sin(cameraPhase) * CameraDistance;
        cameraPos.y = 2;

        Matrix view = Matrix::lookAt(cameraPos, 0);
        Matrix proj = Matrix::projectionPerspective(size());
        c.viewProj = proj * view;
        c.model    = Matrix::axisAngle({1, 0, 0}, Angle(objectPhase));

        cmd.setConstants(c);
        cmd.setShaderView(Hello::tex, lena);
        cmd.drawIndexed(cube.numIndices());

        cmd.setRenderTargets();

        cmd.imguiEndFrame(swapChain);
        device.execute(cmd);
        device.present(swapChain);
    }
Пример #5
0
  static void runTestsForDevice(GpuDevice& dev, GraphicsQueue& queue, Window& window, SwapChain& sc, ViewPort& port, GfxCommandList& gfx, faze::Logger& log)
  {
    faze::TestWorks t("advtests");
    t.setAfterTest([&]()
    {
      // clean up
      auto fence = dev.createFence();
      queue.insertFence(fence);
      fence.wait();
      if (!gfx.isClosed())
      {
        gfx.closeList();
      }
      gfx.resetList();

    });

    
    t.addTest("Lots of drawcalls bench, (single thread), rough baseline", [&]()
    {
      using namespace faze;
      struct buf
      {
        float pos[4];
      };
      auto triangleCount = 1000000;
      auto currentTriangleCount = triangleCount;
	  auto srcdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>()
		  .Usage(ResourceUsage::UploadHeap));
	  auto dstdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>());
      auto dstdataSrv = dev.createBufferSRV(dstdata);

      std::random_device rd;
      std::mt19937 gen(rd());
      std::uniform_real_distribution<> dis(-0.8f, 0.8f);
      std::uniform_real_distribution<> dis2(0.f, 1.f);

      {
        auto tmp = srcdata.Map<buf>();
        for (int i = 0;i < triangleCount; ++i)
        {
          auto& it = tmp[i].pos;
          it[0] = static_cast<float>(dis(gen));
          it[1] = static_cast<float>(dis(gen));
          it[2] = static_cast<float>(dis2(gen));
        }
      }

      gfx.CopyResource(dstdata, srcdata);
      GpuFence fence = dev.createFence();
      gfx.closeList();
      queue.submit(gfx);
      queue.insertFence(fence);

      auto pipeline = dev.createGraphicsPipeline(GraphicsPipelineDescriptor()
        .PixelShader("tests/stress/pixel")
        .VertexShader("tests/stress/vertex_triangle")
        .setRenderTargetCount(1)
        .RTVFormat(0, FormatType::R8G8B8A8_UNORM_SRGB)
        .DepthStencil(DepthStencilDescriptor().DepthEnable(false)));

      auto vec = faze::vec4({ 0.2f, 0.2f, 0.2f, 1.0f });

      fence.wait();
      gfx.resetList();

      WTime t;
      t.firstTick();
      float frameTime = 30.f;
      float cpuTime = 30.f;
      Bentsumaakaa b;

      while (cpuTime > 14.f)
      //while(true)
      {
        if (window.simpleReadMessages())
          break;

        // Rendertarget
        b.start(false);
        gfx.setViewPort(port);
        auto backBufferIndex = sc->GetCurrentBackBufferIndex();
        gfx.ClearRenderTargetView(sc[backBufferIndex], vec);
        gfx.setRenderTarget(sc[backBufferIndex]);
        // graphics begin
        {
          auto bind = gfx.bind(pipeline);
          bind.SRV(0, dstdataSrv);
          gfx.drawInstanced(bind, 3, 1, 0, 0);
          
          for (int i = 1; i < currentTriangleCount; ++i)
          {
            gfx.drawInstancedRaw(3, 1, 0, i); // this is the cheat.
          }
          
        }

        // submit all
        gfx.closeList();
        queue.submit(gfx);
        cpuTime = b.stop(false) / 1000000.f;
        // present
        sc->Present(1, 0);
        queue.insertFence(fence);
        fence.wait();
        gfx.resetList();

        t.tick();
        frameTime = static_cast<float>(t.getCurrentNano())*0.000001f;
        if (cpuTime > 16.f)
        {
          currentTriangleCount -= currentTriangleCount/100;
        }
      }
      F_LOG("frametime: %.3fms CpuTime: %.3fms TriangleCount: %d\n", frameTime, cpuTime, currentTriangleCount);
      log.update();
      //fence.wait();
      return true;
    });

    t.addTest("Lots of drawcalls bench, (single thread), myapi", [&]()
    {
      using namespace faze;
      struct buf
      {
        float pos[4];
      };
      auto triangleCount = 200000;
      auto currentTriangleCount = triangleCount;
	  auto srcdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>()
		  .Usage(ResourceUsage::UploadHeap));
	  auto dstdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>());
	  auto dstdataSrv = dev.createBufferSRV(dstdata);


      std::random_device rd;
      std::mt19937 gen(rd());
      std::uniform_real_distribution<> dis(-0.8f, 0.8f);
      std::uniform_real_distribution<> dis2(0.f, 1.f);

      {
        auto tmp = srcdata.Map<buf>();
        for (int i = 0;i < triangleCount; ++i)
        {
          auto& it = tmp[i].pos;
          it[0] = static_cast<float>(dis(gen));
          it[1] = static_cast<float>(dis(gen));
          it[2] = static_cast<float>(dis2(gen));
        }
      }

      gfx.CopyResource(dstdata, srcdata);
      GpuFence fence = dev.createFence();
      gfx.closeList();
      queue.submit(gfx);
      queue.insertFence(fence);

      auto pipeline = dev.createGraphicsPipeline(GraphicsPipelineDescriptor()
        .PixelShader("tests/stress/pixel")
        .VertexShader("tests/stress/vertex_triangle")
        .setRenderTargetCount(1)
        .RTVFormat(0, FormatType::R8G8B8A8_UNORM_SRGB)
        .DepthStencil(DepthStencilDescriptor().DepthEnable(false)));

      auto vec = faze::vec4({ 0.2f, 0.2f, 0.2f, 1.0f });

      fence.wait();
      gfx.resetList();

      WTime t;
      t.firstTick();
      float frameTime = 30.f;
      float cpuTime = 30.f;
      Bentsumaakaa b;
      LBS lbs;

      while (cpuTime > 14.f)
      //while (true)
      {
        if (window.simpleReadMessages())
          break;

        // Rendertarget
        b.start(false);
        gfx.setViewPort(port);
        auto backBufferIndex = sc->GetCurrentBackBufferIndex();
        gfx.ClearRenderTargetView(sc[backBufferIndex], vec);
        gfx.setRenderTarget(sc[backBufferIndex]);
        // graphics begin
        {
          for (int i = 0; i < currentTriangleCount; ++i)
          {
            auto bind = gfx.bind(pipeline);
            bind.SRV(0, dstdataSrv);
            gfx.drawInstanced(bind, 3, 1, 0, i);
          }
        }

        // submit all
        gfx.closeList();
        queue.submit(gfx);
        cpuTime = b.stop(false) / 1000000.f;
        // present
        sc->Present(1, 0);
        queue.insertFence(fence);
        fence.wait();
        gfx.resetList();

        t.tick();
        frameTime = static_cast<float>(t.getCurrentNano())*0.000001f;
        frameTime = t.analyzeFrames().x();
        if (cpuTime > 16.f)
        {
          currentTriangleCount -= currentTriangleCount / 100;
        }
      }
      //fence.wait();
      F_LOG("frametime: %.3fms CpuTime: %.3fms TriangleCount: %d\n", frameTime, cpuTime, currentTriangleCount);
      log.update();
      return true;
    });

    t.addTest("Lots of drawcalls bench, (Multithread), baseline", [&]()
    {
      using namespace faze;
      struct buf
      {
        float pos[4];
      };
      auto triangleCount = 4000000;
      auto currentTriangleCount = triangleCount;
	  auto srcdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>()
		  .Usage(ResourceUsage::UploadHeap));
	  auto dstdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>());
	  auto dstdataSrv = dev.createBufferSRV(dstdata);

      std::random_device rd;
      std::mt19937 gen(rd());
      std::uniform_real_distribution<> dis(-0.8f, 0.8f);
      std::uniform_real_distribution<> dis2(0.f, 1.f);

      {
        auto tmp = srcdata.Map<buf>();
        for (int i = 0;i < triangleCount; ++i)
        {
          auto& it = tmp[i].pos;
          it[0] = static_cast<float>(dis(gen));
          it[1] = static_cast<float>(dis(gen));
          it[2] = static_cast<float>(dis2(gen));
        }
      }

      gfx.CopyResource(dstdata, srcdata);
      GpuFence fence = dev.createFence();
      gfx.closeList();
      queue.submit(gfx);
      queue.insertFence(fence);

      auto pipeline = dev.createGraphicsPipeline(GraphicsPipelineDescriptor()
        .PixelShader("tests/stress/pixel")
        .VertexShader("tests/stress/vertex_triangle")
        .setRenderTargetCount(1)
        .RTVFormat(0, FormatType::R8G8B8A8_UNORM_SRGB)
        .DepthStencil(DepthStencilDescriptor().DepthEnable(false)));

      auto vec = faze::vec4({ 0.2f, 0.2f, 0.2f, 1.0f });

      fence.wait();
      gfx.resetList();

      WTime t;
      t.firstTick();
      float frameTime = 30.f;
      float cpuTime = 30.f;
      Bentsumaakaa b;
      LBS lbs;
      std::vector<GfxCommandList> m_cmds;
      for (size_t i = 0; i < lbs.threadCount(); ++i)
      {
        m_cmds.push_back(dev.createUniversalCommandList());
      }
      //while (true)
      while (cpuTime > 14.f)
      {
        if (window.simpleReadMessages())
          break;

        // Rendertarget
        b.start(false);
        m_cmds[0].setViewPort(port);
        auto backBufferIndex = sc->GetCurrentBackBufferIndex();
        m_cmds[0].ClearRenderTargetView(sc[backBufferIndex], vec);
        m_cmds[0].setRenderTarget(sc[backBufferIndex]);
        for (size_t i = 1; i < lbs.threadCount(); ++i)
        {
          m_cmds[i].setViewPort(port);
          //m_cmds[i].ClearRenderTargetView(sc[backBufferIndex], vec);
          m_cmds[i].setRenderTarget(sc[backBufferIndex]);
        }
        // graphics begin
        lbs.addParallelFor<1>("fillCommands", {}, {}, 0, 100, [&](size_t id, size_t threadIndex)
        {
          auto& gfx2 = m_cmds[threadIndex];
          unsigned workAmount = currentTriangleCount / 100;
          unsigned startIndex = static_cast<unsigned>(workAmount * id);
          auto bind = gfx2.bind(pipeline);
          bind.SRV(0, dstdataSrv);
          gfx2.drawInstanced(bind, 3, 1, 0, startIndex);
          for (unsigned i = startIndex+1; i < startIndex + workAmount; ++i)
          {
            gfx2.drawInstancedRaw(3, 1, 0, i);
          }
        });
        lbs.sleepTillKeywords({ "fillCommands" });
        for (size_t i = 0; i < lbs.threadCount(); ++i)
        {
          m_cmds[i].closeList();
          queue.submit(m_cmds[i]);
        }
        cpuTime = b.stop(false) / 1000000.f;
        // present
        sc->Present(1, 0);
        queue.insertFence(fence);
        fence.wait();
        for (size_t i = 0; i < lbs.threadCount(); ++i)
        {
          m_cmds[i].resetList();
        }

        t.tick();
        frameTime = static_cast<float>(t.getCurrentNano())*0.000001f;
        frameTime = t.analyzeFrames().x();
        if (cpuTime > 16.f)
        {
          currentTriangleCount -= currentTriangleCount / 100;
        }
      }
      F_LOG("frametime: %.3fms CpuTime: %.3fms TriangleCount: %d\n", frameTime, cpuTime, currentTriangleCount);
      log.update();
      return true;
    });

    t.addTest("Lots of drawcalls bench, (Multithread), myapi", [&]()
    {
      using namespace faze;
      struct buf
      {
        float pos[4];
      };
      auto triangleCount = 2000000;
      auto currentTriangleCount = triangleCount;
	  auto srcdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>()
		  .Usage(ResourceUsage::UploadHeap));
	  auto dstdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>());
	  auto dstdataSrv = dev.createBufferSRV(dstdata);

      std::random_device rd;
      std::mt19937 gen(rd());
      std::uniform_real_distribution<> dis(-0.8f, 0.8f);
      std::uniform_real_distribution<> dis2(0.f, 1.f);

      {
        auto tmp = srcdata.Map<buf>();
        for (int i = 0;i < triangleCount; ++i)
        {
          auto& it = tmp[i].pos;
          it[0] = static_cast<float>(dis(gen));
          it[1] = static_cast<float>(dis(gen));
          it[2] = static_cast<float>(dis2(gen));
        }
      }

      gfx.CopyResource(dstdata, srcdata);
      GpuFence fence = dev.createFence();
      gfx.closeList();
      queue.submit(gfx);
      queue.insertFence(fence);

      auto pipeline = dev.createGraphicsPipeline(GraphicsPipelineDescriptor()
        .PixelShader("tests/stress/pixel")
        .VertexShader("tests/stress/vertex_triangle")
        .setRenderTargetCount(1)
        .RTVFormat(0, FormatType::R8G8B8A8_UNORM_SRGB)
        .DepthStencil(DepthStencilDescriptor().DepthEnable(false)));

      auto vec = faze::vec4({ 0.2f, 0.2f, 0.2f, 1.0f });

      fence.wait();
      gfx.resetList();

      WTime t;
      t.firstTick();
      float frameTime = 30.f;
      float cpuTime = 30.f;
      Bentsumaakaa b;
      LBS lbs;
      std::vector<GfxCommandList> m_cmds;
      for (size_t i = 0; i < lbs.threadCount(); ++i)
      {
        m_cmds.push_back(dev.createUniversalCommandList());
      }
      //while (true)
      while (cpuTime > 14.f)
      {
        if (window.simpleReadMessages())
          break;

        // Rendertarget
        b.start(false);
        m_cmds[0].setViewPort(port);
        auto backBufferIndex = sc->GetCurrentBackBufferIndex();
        m_cmds[0].ClearRenderTargetView(sc[backBufferIndex], vec);
        m_cmds[0].setRenderTarget(sc[backBufferIndex]);
        for (size_t i = 1; i < lbs.threadCount(); ++i)
        {
          m_cmds[i].setViewPort(port);
          //m_cmds[i].ClearRenderTargetView(sc[backBufferIndex], vec);
          m_cmds[i].setRenderTarget(sc[backBufferIndex]);
        }
        // graphics begin
        lbs.addParallelFor<1>("fillCommands", {}, {}, 0, 100, [&](size_t id, size_t threadIndex)
        {
          auto& gfx2 = m_cmds[threadIndex];
          unsigned workAmount = currentTriangleCount / 100;
          unsigned startIndex = static_cast<unsigned>(workAmount * id);
          for (unsigned i = startIndex; i < startIndex + workAmount; ++i)
          {
            auto bind = gfx2.bind(pipeline);
            bind.SRV(0, dstdataSrv);
            gfx2.drawInstanced(bind, 3, 1, 0, i);
          }
        });
        lbs.sleepTillKeywords({ "fillCommands" });
        for (size_t i = 0; i < lbs.threadCount(); ++i)
        {
          m_cmds[i].closeList();
          queue.submit(m_cmds[i]);
        }
        cpuTime = b.stop(false) / 1000000.f;
        // present
        sc->Present(1, 0);
        queue.insertFence(fence);
        fence.wait();
        for (size_t i = 0; i < lbs.threadCount(); ++i)
        {
          m_cmds[i].resetList();
        }

        t.tick();
        frameTime = static_cast<float>(t.getCurrentNano())*0.000001f;
        frameTime = t.analyzeFrames().x();
        if (cpuTime > 16.f)
        {
          currentTriangleCount -= currentTriangleCount / 40;
        }
      }
      F_LOG("frametime: %.3fms CpuTime: %.3fms TriangleCount: %d\n", frameTime, cpuTime, currentTriangleCount);
      log.update();
      return true;
    });

    t.addTest("Lots of drawcalls bench, (single thread), rough baseline, frametime 20ms", [&]()
    {
      using namespace faze;
      struct buf
      {
        float pos[4];
      };
      auto triangleCount = 800000;
      auto currentTriangleCount = triangleCount;
	  auto srcdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>()
		  .Usage(ResourceUsage::UploadHeap));
	  auto dstdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>());
	  auto dstdataSrv = dev.createBufferSRV(dstdata);

      std::random_device rd;
      std::mt19937 gen(rd());
      std::uniform_real_distribution<> dis(-0.8f, 0.8f);
      std::uniform_real_distribution<> dis2(0.f, 1.f);

      {
        auto tmp = srcdata.Map<buf>();
        for (int i = 0;i < triangleCount; ++i)
        {
          auto& it = tmp[i].pos;
          it[0] = static_cast<float>(dis(gen));
          it[1] = static_cast<float>(dis(gen));
          it[2] = static_cast<float>(dis2(gen));
        }
      }

      gfx.CopyResource(dstdata, srcdata);
      GpuFence fence = dev.createFence();
      gfx.closeList();
      queue.submit(gfx);
      queue.insertFence(fence);
      fence.wait();
      gfx.resetList();

      auto pipeline = dev.createGraphicsPipeline(GraphicsPipelineDescriptor()
        .PixelShader("tests/stress/pixel")
        .VertexShader("tests/stress/vertex_triangle")
        .setRenderTargetCount(1)
        .RTVFormat(0, FormatType::R8G8B8A8_UNORM_SRGB)
        .DepthStencil(DepthStencilDescriptor().DepthEnable(false)));

      auto vec = faze::vec4({ 0.2f, 0.2f, 0.2f, 1.0f });


      WTime t;
      t.firstTick();
      float frameTime = 30.f;
      float cpuTime = 30.f;
      Bentsumaakaa b;

      int beenUnderLimit = 0;
      while (beenUnderLimit < 10)
      {
        if (frameTime < 20.f)
          beenUnderLimit++;
        if (window.simpleReadMessages())
          break;

        // Rendertarget
        b.start(false);
        gfx.setViewPort(port);
        auto backBufferIndex = sc->GetCurrentBackBufferIndex();
        gfx.ClearRenderTargetView(sc[backBufferIndex], vec);
        gfx.setRenderTarget(sc[backBufferIndex]);
        // graphics begin
        {
          auto bind = gfx.bind(pipeline);
          bind.SRV(0, dstdataSrv);
          gfx.drawInstanced(bind, 3, 1, 0, 0);

          for (int i = 1; i < currentTriangleCount; ++i)
          {
            gfx.drawInstancedRaw(3, 1, 0, i); // this is the cheat.
          }

        }

        // submit all
        gfx.closeList();
        queue.submit(gfx);
        cpuTime = b.stop(false) / 1000000.f;
        // present
        sc->Present(1, 0);
        queue.insertFence(fence);
        fence.wait();
        gfx.resetList();

        t.tick();
        frameTime = static_cast<float>(t.getCurrentNano())*0.000001f;
        if (frameTime > 20.f)
        {
          currentTriangleCount -= currentTriangleCount / 100;
        }
      }
      F_LOG("frametime: %.3fms CpuTime: %.3fms TriangleCount: %d\n", frameTime, cpuTime, currentTriangleCount);
      log.update();
      //fence.wait();
      return true;
    });

    t.addTest("Lots of drawcalls bench, (single thread), myapi, frametime 20ms", [&]()
    {
      using namespace faze;
      struct buf
      {
        float pos[4];
      };
      auto triangleCount = 100000;
      auto currentTriangleCount = triangleCount;
	  auto srcdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>()
		  .Usage(ResourceUsage::UploadHeap));
	  auto dstdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>());
	  auto dstdataSrv = dev.createBufferSRV(dstdata);

      std::random_device rd;
      std::mt19937 gen(rd());
      std::uniform_real_distribution<> dis(-0.8f, 0.8f);
      std::uniform_real_distribution<> dis2(0.f, 1.f);

      {
        auto tmp = srcdata.Map<buf>();
        for (int i = 0;i < triangleCount; ++i)
        {
          auto& it = tmp[i].pos;
          it[0] = static_cast<float>(dis(gen));
          it[1] = static_cast<float>(dis(gen));
          it[2] = static_cast<float>(dis2(gen));
        }
      }

      gfx.CopyResource(dstdata, srcdata);
      GpuFence fence = dev.createFence();
      gfx.closeList();
      queue.submit(gfx);
      queue.insertFence(fence);

      auto pipeline = dev.createGraphicsPipeline(GraphicsPipelineDescriptor()
        .PixelShader("tests/stress/pixel")
        .VertexShader("tests/stress/vertex_triangle")
        .setRenderTargetCount(1)
        .RTVFormat(0, FormatType::R8G8B8A8_UNORM_SRGB)
        .DepthStencil(DepthStencilDescriptor().DepthEnable(false)));

      auto vec = faze::vec4({ 0.2f, 0.2f, 0.2f, 1.0f });

      fence.wait();
      gfx.resetList();

      WTime t;
      t.firstTick();
      float frameTime = 30.f;
      float cpuTime = 30.f;
      Bentsumaakaa b;
      LBS lbs;

      int beenUnderLimit = 0;
      while (beenUnderLimit < 10)
      {
        if (frameTime < 20.f)
          beenUnderLimit++;
        if (window.simpleReadMessages())
          break;

        // Rendertarget
        b.start(false);
        gfx.setViewPort(port);
        auto backBufferIndex = sc->GetCurrentBackBufferIndex();
        gfx.ClearRenderTargetView(sc[backBufferIndex], vec);
        gfx.setRenderTarget(sc[backBufferIndex]);
        // graphics begin
        {
          for (int i = 0; i < currentTriangleCount; ++i)
          {
            auto bind = gfx.bind(pipeline);
            bind.SRV(0, dstdataSrv);
            gfx.drawInstanced(bind, 3, 1, 0, i);
          }
        }

        // submit all
        gfx.closeList();
        queue.submit(gfx);
        cpuTime = b.stop(false) / 1000000.f;
        // present
        sc->Present(1, 0);
        queue.insertFence(fence);
        fence.wait();
        gfx.resetList();

        t.tick();
        frameTime = static_cast<float>(t.getCurrentNano())*0.000001f;
        //frameTime = t.analyzeFrames().x();
        if (frameTime > 20.f)
        {
          currentTriangleCount -= currentTriangleCount / 100;
        }
      }
      //fence.wait();
      F_LOG("frametime: %.3fms CpuTime: %.3fms TriangleCount: %d\n", frameTime, cpuTime, currentTriangleCount);
      log.update();
      return true;
    });

    t.addTest("Lots of drawcalls bench, (Multithread), baseline, frametime 20ms", [&]()
    {
      using namespace faze;
      struct buf
      {
        float pos[4];
      };
      auto triangleCount = 1000000;
      auto currentTriangleCount = triangleCount;
	  auto srcdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>()
		  .Usage(ResourceUsage::UploadHeap));
	  auto dstdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>());
	  auto dstdataSrv = dev.createBufferSRV(dstdata);

      std::random_device rd;
      std::mt19937 gen(rd());
      std::uniform_real_distribution<> dis(-0.8f, 0.8f);
      std::uniform_real_distribution<> dis2(0.f, 1.f);

      {
        auto tmp = srcdata.Map<buf>();
        for (int i = 0;i < triangleCount; ++i)
        {
          auto& it = tmp[i].pos;
          it[0] = static_cast<float>(dis(gen));
          it[1] = static_cast<float>(dis(gen));
          it[2] = static_cast<float>(dis2(gen));
        }
      }

      gfx.CopyResource(dstdata, srcdata);
      GpuFence fence = dev.createFence();
      gfx.closeList();
      queue.submit(gfx);
      queue.insertFence(fence);

      auto pipeline = dev.createGraphicsPipeline(GraphicsPipelineDescriptor()
        .PixelShader("tests/stress/pixel")
        .VertexShader("tests/stress/vertex_triangle")
        .setRenderTargetCount(1)
        .RTVFormat(0, FormatType::R8G8B8A8_UNORM_SRGB)
        .DepthStencil(DepthStencilDescriptor().DepthEnable(false)));

      auto vec = faze::vec4({ 0.2f, 0.2f, 0.2f, 1.0f });

      fence.wait();
      gfx.resetList();

      WTime t;
      t.firstTick();
      float frameTime = 30.f;
      float cpuTime = 30.f;
      Bentsumaakaa b;
      LBS lbs;
      std::vector<GfxCommandList> m_cmds;
      for (size_t i = 0; i < lbs.threadCount(); ++i)
      {
        m_cmds.push_back(dev.createUniversalCommandList());
      }
      //while (true)
      int beenUnderLimit = 0;
      while (beenUnderLimit < 10)
      {
        if (frameTime < 20.f)
          beenUnderLimit++;
        if (window.simpleReadMessages())
          break;

        // Rendertarget
        b.start(false);
        m_cmds[0].setViewPort(port);
        auto backBufferIndex = sc->GetCurrentBackBufferIndex();
        m_cmds[0].ClearRenderTargetView(sc[backBufferIndex], vec);
        m_cmds[0].setRenderTarget(sc[backBufferIndex]);
        for (size_t i = 1; i < lbs.threadCount(); ++i)
        {
          m_cmds[i].setViewPort(port);
          //m_cmds[i].ClearRenderTargetView(sc[backBufferIndex], vec);
          m_cmds[i].setRenderTarget(sc[backBufferIndex]);
        }
        // graphics begin
        lbs.addParallelFor<1>("fillCommands", {}, {}, 0, 100, [&](size_t id, size_t threadIndex)
        {
          auto& gfx2 = m_cmds[threadIndex];
          unsigned workAmount = static_cast<unsigned>(currentTriangleCount / 100);
          unsigned startIndex = static_cast<unsigned>(workAmount * id);
          auto bind = gfx2.bind(pipeline);
          bind.SRV(0, dstdataSrv);
          gfx2.drawInstanced(bind, 3, 1, 0, startIndex);
          for (unsigned i = startIndex + 1; i < startIndex + workAmount; ++i)
          {
            gfx2.drawInstancedRaw(3, 1, 0, i);
          }
        });
        lbs.sleepTillKeywords({ "fillCommands" });
        for (size_t i = 0; i < lbs.threadCount(); ++i)
        {
          m_cmds[i].closeList();
          queue.submit(m_cmds[i]);
        }
        cpuTime = b.stop(false) / 1000000.f;
        // present
        sc->Present(1, 0);
        queue.insertFence(fence);
        fence.wait();
        for (size_t i = 0; i < lbs.threadCount(); ++i)
        {
          m_cmds[i].resetList();
        }

        t.tick();
        frameTime = static_cast<float>(t.getCurrentNano())*0.000001f;
        //frameTime = t.analyzeFrames().x();
        if (frameTime > 20.f)
        {
          currentTriangleCount -= currentTriangleCount / 120;
        }
      }
      F_LOG("frametime: %.3fms CpuTime: %.3fms TriangleCount: %d\n", frameTime, cpuTime, currentTriangleCount);
      log.update();
      return true;
    });

    t.addTest("Lots of drawcalls bench, (Multithread), myapi, frametime 20ms", [&]()
    {
      using namespace faze;
      struct buf
      {
        float pos[4];
      };
      auto triangleCount = 400000;
      auto currentTriangleCount = triangleCount;
	  auto srcdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>()
		  .Usage(ResourceUsage::UploadHeap));
	  auto dstdata = dev.createBuffer(ResourceDescriptor()
		  .Width(triangleCount)
		  .Format<buf>());
	  auto dstdataSrv = dev.createBufferSRV(dstdata);

      std::random_device rd;
      std::mt19937 gen(rd());
      std::uniform_real_distribution<> dis(-0.8f, 0.8f);
      std::uniform_real_distribution<> dis2(0.f, 1.f);

      {
        auto tmp = srcdata.Map<buf>();
        for (int i = 0;i < triangleCount; ++i)
        {
          auto& it = tmp[i].pos;
          it[0] = static_cast<float>(dis(gen));
          it[1] = static_cast<float>(dis(gen));
          it[2] = static_cast<float>(dis2(gen));
        }
      }

      gfx.CopyResource(dstdata, srcdata);
      GpuFence fence = dev.createFence();
      gfx.closeList();
      queue.submit(gfx);
      queue.insertFence(fence);

      auto pipeline = dev.createGraphicsPipeline(GraphicsPipelineDescriptor()
        .PixelShader("tests/stress/pixel")
        .VertexShader("tests/stress/vertex_triangle")
        .setRenderTargetCount(1)
        .RTVFormat(0, FormatType::R8G8B8A8_UNORM_SRGB)
        .DepthStencil(DepthStencilDescriptor().DepthEnable(false)));

      auto vec = faze::vec4({ 0.2f, 0.2f, 0.2f, 1.0f });

      fence.wait();
      gfx.resetList();

      WTime t;
      t.firstTick();
      float frameTime = 30.f;
      float cpuTime = 30.f;
      Bentsumaakaa b;
      LBS lbs;
      std::vector<GfxCommandList> m_cmds;
      for (size_t i = 0; i < lbs.threadCount(); ++i)
      {
        m_cmds.push_back(dev.createUniversalCommandList());
      }
      //while (true)
      int beenUnderLimit = 0;
      while (beenUnderLimit < 10)
      {
        if (frameTime < 20.f)
          beenUnderLimit++;
        if (window.simpleReadMessages())
          break;

        // Rendertarget
        b.start(false);
        m_cmds[0].setViewPort(port);
        auto backBufferIndex = sc->GetCurrentBackBufferIndex();
        m_cmds[0].ClearRenderTargetView(sc[backBufferIndex], vec);
        m_cmds[0].setRenderTarget(sc[backBufferIndex]);
        for (size_t i = 1; i < lbs.threadCount(); ++i)
        {
          m_cmds[i].setViewPort(port);
          //m_cmds[i].ClearRenderTargetView(sc[backBufferIndex], vec);
          m_cmds[i].setRenderTarget(sc[backBufferIndex]);
        }
        // graphics begin
        lbs.addParallelFor<1>("fillCommands", {}, {}, 0, 100, [&](size_t id, size_t threadIndex)
        {
          auto& gfx2 = m_cmds[threadIndex];
          size_t workAmount = currentTriangleCount / 100;
          size_t startIndex = workAmount * id;
          for (unsigned i = static_cast<unsigned>(startIndex); i < static_cast<unsigned>(startIndex + workAmount); ++i)
          {
            auto bind = gfx2.bind(pipeline);
            bind.SRV(0, dstdataSrv);
            gfx2.drawInstanced(bind, 3, 1, 0, i);
          }
        });
        lbs.sleepTillKeywords({ "fillCommands" });
        for (size_t i = 0; i < lbs.threadCount(); ++i)
        {
          m_cmds[i].closeList();
          queue.submit(m_cmds[i]);
        }
        cpuTime = b.stop(false) / 1000000.f;
        // present
        sc->Present(1, 0);
        queue.insertFence(fence);
        fence.wait();
        for (size_t i = 0; i < lbs.threadCount(); ++i)
        {
          m_cmds[i].resetList();
        }

        t.tick();
        frameTime = static_cast<float>(t.getCurrentNano())*0.000001f;
        //frameTime = t.analyzeFrames().x();
        if (frameTime > 20.f)
        {
          currentTriangleCount -= currentTriangleCount / 120;
        }
      }
      F_LOG("frametime: %.3fms CpuTime: %.3fms TriangleCount: %d\n", frameTime, cpuTime, currentTriangleCount);
      log.update();
      return true;
    });

    t.runTests();
  }
Пример #6
0
std::unique_ptr<SwapChain> SwapChain_<>::Create( const Config &config ) {
	SwapChain* retval = nullptr;

#if defined(LUDI_PLATFORM_XENON)
	retval = nullptr;
#elif defined(LUDI_PLATFORM_PS3)
	retval = nullptr;
#elif defined(LUDI_PLATFORM_WII)
	retval = nullptr;
#elif LUDI_PLATFORM_ID == LUDI_PLATFORM_WINDOWS
	// Attempt to get  the DXGI Factory.
	Device* device = Device::Get();
	Driver* driver = device->driver();
	
	// Attempt to create the swap chain.
	IDXGISwapChain* chain = nullptr;

	// Create the swap chain
	DXGI_SWAP_CHAIN_DESC desc;	 
	desc = ConversionDx11::To(config);

	HRESULT hresult = driver->factory()->CreateSwapChain(device->device(), &desc, &chain);
	if (FAILED(hresult)) {
		//Log::Get().Write( L"Failed to create swap chain!" );
		ASSERT(false);
		return nullptr;
	}

	// Retrieve the texture buffer (render-texture)
	ID3D11Texture2D* texture = nullptr;
	hresult = chain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast< void** >( &texture ) );
	if (FAILED(hresult)) {
		//Log::Get().Write( L"Failed to get swap chain texture resource!" );
		ASSERT(false);
		return nullptr;
	}
		
	// Create the swap chain render target view
	ID3D11RenderTargetView* view;
	hresult = (*device)->CreateRenderTargetView(texture, nullptr, &view);
	if (FAILED(hresult)) {
		//Log::Get().Write( L"Failed to create render target view for swap chain!" );
		ASSERT(false);
		return nullptr;
	}

	// Create the swap chain, set the render texture and render target view
	retval = new SwapChain_<LUDI_PLATFORM_WINDOWS>(chain);

	retval->set_render_texture(new Texture(texture));	
	retval->set_render_target_view(new RenderTargetView(view));

#elif LUDI_PLATFORM_ID == LUDI_PLATFORM_OSX
    retval = new SwapChain_<LUDI_PLATFORM_OSX>(nullptr);
    
   	retval->set_render_texture(new Texture());
	retval->set_render_target_view(new RenderTargetView());
 
#else // NO VALID PLATFORM
	retval = nullptr;
#endif
	
	return std::unique_ptr<SwapChain>(retval);
}