Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nvidia atw updates #355

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions examples/RenderManagerD3DATWDoubleBufferExample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Russ Taylor <[email protected]>
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
#include <stdlib.h> // For exit()

using namespace DirectX;
Expand Down Expand Up @@ -117,7 +118,7 @@ void RenderView(

// draw room
simpleShader.use(device, context, xm_projectionD3D, xm_viewD3D, identity);
roomCube.draw(device, context);
roomCube.draw(device, context);
}

void Usage(std::string name) {
Expand All @@ -135,8 +136,10 @@ struct FrameInfo {
};

int main(int argc, char* argv[]) {
std::cout << "Render thread id: " << std::this_thread::get_id() << std::endl;

// Parse the command line
int delayMilliSeconds = 500;
int delayMilliSeconds = 0;
int realParams = 0;
for (int i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
Expand Down
260 changes: 148 additions & 112 deletions examples/RenderManagerD3DCAPIExample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <string>
#include <stdlib.h> // For exit()
#include <chrono>
#include <thread>

using namespace DirectX;

Expand Down Expand Up @@ -88,8 +89,8 @@ void myButtonCallback(void* userdata, const OSVR_TimeValue* /*timestamp*/,
// Callbacks to draw things in world space, left-hand space, and right-hand
// space.
void RenderView(
const OSVR_RenderInfoD3D11& renderInfo //< Info needed to render
,
size_t eye,
const OSVR_RenderInfoD3D11& renderInfo, //< Info needed to render
ID3D11RenderTargetView* renderTargetView,
ID3D11DepthStencilView* depthStencilView) {

Expand All @@ -103,17 +104,12 @@ void RenderView(
context->OMSetRenderTargets(1, &renderTargetView, depthStencilView);

// Set up the viewport we're going to draw into.
CD3D11_VIEWPORT viewport(static_cast<float>(renderInfo.viewport.left),
static_cast<float>(renderInfo.viewport.lower),
static_cast<float>(renderInfo.viewport.width),
static_cast<float>(renderInfo.viewport.height));
context->RSSetViewports(1, &viewport);
CD3D11_VIEWPORT viewport(static_cast<float>(eye == 0 ? 0 : renderInfo.viewport.width),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be handled by RenderManager, not by the application. The viewport should have been set correctly by the osvrRenderManagerGetRenderInfoFromCollectionD3D11() call.

static_cast<float>(renderInfo.viewport.lower),
static_cast<float>(renderInfo.viewport.width),
static_cast<float>(renderInfo.viewport.height));

// Make a grey background
FLOAT colorRgba[4] = {0.3f, 0.3f, 0.3f, 1.0f};
context->ClearRenderTargetView(renderTargetView, colorRgba);
context->ClearDepthStencilView(
depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
context->RSSetViewports(1, &viewport);

OSVR_PoseState_to_D3D(viewD3D, renderInfo.pose);
OSVR_Projection_to_D3D(projectionD3D,
Expand All @@ -132,6 +128,7 @@ void Usage(std::string name) {
}

int main(int argc, char* argv[]) {
std::cout << "Render thread id: " << std::this_thread::get_id();
// Parse the command line
int realParams = 0;
for (int i = 1; i < argc; i++) {
Expand All @@ -153,6 +150,23 @@ int main(int argc, char* argv[]) {
osvr::clientkit::ClientContext context(
"osvr.RenderManager.D3DPresentExample3D");

// Wait for good status on context
{
auto ctxInitStart = std::chrono::system_clock::now();
bool timeout = false;
do {
context.update();
auto ctxInitEnd = std::chrono::system_clock::now();
std::chrono::duration<double> elapsedSec = ctxInitEnd - ctxInitStart;
int secs = static_cast<int>(elapsedSec.count());
timeout = secs >= 2;
} while (!context.checkStatus() && !timeout);
if (timeout) {
std::cerr << "Timed out waiting for the ClientContext to connect to the OSVR server.";
return 1;
}
}

// Construct button devices and connect them to a callback
// that will set the "quit" variable to true when it is
// pressed. Use button "1" on the left-hand or
Expand Down Expand Up @@ -246,22 +260,23 @@ int main(int argc, char* argv[]) {
std::vector<ID3D11Texture2D*> depthStencilTextures;
std::vector<ID3D11DepthStencilView*> depthStencilViews;

double width = renderInfo[0].viewport.width + renderInfo[1].viewport.width;
double height = renderInfo[0].viewport.height;

HRESULT hr;
for (size_t i = 0; i < numRenderInfo; i++) {
for (size_t i = 0; i < 2; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why make this less general? A monocular view onscreen is possible when we use numRenderInfo and not when we use 2.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 2 here has a different meaning than the numRenderInfo it replaces. It's no longer the number of render info but the number of buffers in the client-side swap chain, which the client controls and which we only support 1 or 2 at the moment.

For reference, these are the only configurations we support at the moment (i.e. for RegisterRenderBuffers):
1 buffer, false for clientWillNotOverwrite: both eyes in one buffer, single buffered (texture copy)
2 buffers, false for clientWillNotOverwrite: one buffer per eye, single buffered (texture copy)
2 buffers, true for clientWillNotOverwrite: both eyes in one buffer, double buffered (NO texture copy)
4 buffers, true for clientWillNotOverwrite: one buffer per eye, double buffered (NO texture copy)

RenderManager currently has no generic way to support all scenarios and so the client has to make assumptions in order to fit into one of the four supported configurations above - e.g. that there are going to be two render infos, each corresponding to an eye. Ideally, the client would request the suggested viewports and buffer sizes and number for a given client preference (one buffer per eye or all eyes in one buffer X double buffered or not double buffered) and then RenderManager would give the client 1) how many buffers to create, 2) what sizes for each buffer, 3) which RenderInfos to render for which buffers and 4) what viewports on THOSE buffers to use (as opposed to the viewports RenderInfo has, which assumes one buffer per eye).


// The color buffer for this eye. We need to put this into
// a generic structure for the Present function, but we only need
// to fill in the Direct3D portion.
// Note that this texture format must be RGBA and unsigned byte,
// so that we can present it to Direct3D for DirectMode.
ID3D11Texture2D* D3DTexture = nullptr;
unsigned width = static_cast<int>(renderInfo[i].viewport.width);
unsigned height = static_cast<int>(renderInfo[i].viewport.height);

// Initialize a new render target texture description.
D3D11_TEXTURE2D_DESC textureDesc = {};
textureDesc.Width = width;
textureDesc.Height = height;
textureDesc.Width = static_cast<UINT>(width);
textureDesc.Height = static_cast<UINT>(height);
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
Expand Down Expand Up @@ -317,8 +332,8 @@ int main(int argc, char* argv[]) {
textureDescription.SampleDesc.Quality = 0;
textureDescription.Usage = D3D11_USAGE_DEFAULT;
textureDescription.BindFlags = D3D11_BIND_DEPTH_STENCIL;
textureDescription.Width = width;
textureDescription.Height = height;
textureDescription.Width = static_cast<UINT>(width);
textureDescription.Height = static_cast<UINT>(height);
textureDescription.MipLevels = 1;
textureDescription.ArraySize = 1;
textureDescription.CPUAccessFlags = 0;
Expand Down Expand Up @@ -370,8 +385,7 @@ int main(int argc, char* argv[]) {

// Front-facing stencil operations
depthStencilDescription.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDescription.FrontFace.StencilDepthFailOp =
D3D11_STENCIL_OP_INCR;
depthStencilDescription.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
depthStencilDescription.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDescription.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

Expand Down Expand Up @@ -399,7 +413,7 @@ int main(int argc, char* argv[]) {
osvrDestroyRenderManager(render);
return -4;
}
for (size_t i = 0; i < numRenderInfo; i++) {
for (size_t i = 0; i < renderBuffers.size(); i++) {
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerRegisterRenderBufferD3D11(
registerBufferState, renderBuffers[i]))) {
std::cerr << "Could not register render buffer " << i << std::endl;
Expand All @@ -408,107 +422,129 @@ int main(int argc, char* argv[]) {
}
}
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerFinishRegisterRenderBuffers(
render, registerBufferState, false))) {
render, registerBufferState, true))) {
std::cerr << "Could not start finish registering render buffers" << std::endl;
osvrDestroyRenderManager(render);
return -6;
}

// Timing of frame rates
size_t count = 0;
size_t frameIndex = 0;
std::chrono::time_point<std::chrono::system_clock> start, end;
start = std::chrono::system_clock::now();

// Continue rendering until it is time to quit.
while (!quit) {
// Update the context so we get our callbacks called and
// update tracker state.
context.update();

if ((OSVR_RETURN_SUCCESS != osvrRenderManagerGetRenderInfoCollection(
render, renderParams, &renderInfoCollection))) {
std::cerr << "Could not get render info" << std::endl;
osvrDestroyRenderManager(render);
return 105;
}
osvrRenderManagerGetNumRenderInfoInCollection(renderInfoCollection, &numRenderInfo);


renderInfo.clear();
for (OSVR_RenderInfoCount i = 0; i < numRenderInfo; i++) {
OSVR_RenderInfoD3D11 info;
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerGetRenderInfoFromCollectionD3D11(
renderInfoCollection, i, &info))) {
std::cerr << "Could not get render info " << i
<< std::endl;
osvrDestroyRenderManager(render);
return 106;
}
renderInfo.push_back(info);
}
osvrRenderManagerReleaseRenderInfoCollection(renderInfoCollection);

// Render into each buffer using the specified information.
for (size_t i = 0; i < renderInfo.size(); i++) {
renderInfo[i].library.context->OMSetDepthStencilState(
depthStencilState, 1);
RenderView(renderInfo[i], renderBuffers[i].colorBufferView,
depthStencilViews[i]);
}

// Every other second, we show a black screen to test how
// a game engine might blank it between scenes. Every even
// second, we display the video.
end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_sec = end - start;
int secs = static_cast<int>(elapsed_sec.count());

if (secs % 2 == 0) {
// Send the rendered results to the screen
OSVR_RenderManagerPresentState presentState;
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerStartPresentRenderBuffers(
&presentState))) {
std::cerr << "Could not start presenting render buffers" << std::endl;
osvrDestroyRenderManager(render);
return 201;
}
OSVR_ViewportDescription fullView;
fullView.left = fullView.lower = 0;
fullView.width = fullView.height = 1;
for (size_t i = 0; i < numRenderInfo; i++) {
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerPresentRenderBufferD3D11(
presentState, renderBuffers[i], renderInfo[i], fullView))) {
std::cerr << "Could not present render buffer " << i << std::endl;
osvrDestroyRenderManager(render);
return 202;
}
}
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerFinishPresentRenderBuffers(
render, presentState, renderParams, false))) {
std::cerr << "Could not finish presenting render buffers" << std::endl;
osvrDestroyRenderManager(render);
return 203;
}
} else {
// send a black screen.
OSVR_RGB_FLOAT black;
black.r = black.g = black.b = 0;
osvrRenderManagerPresentSolidColorf(render, black);
}

// Timing information
if (elapsed_sec.count() >= 2) {
std::chrono::duration<double, std::micro> elapsed_usec =
end - start;
double usec = elapsed_usec.count();
std::cout << "Rendering at " << count / (usec * 1e-6) << " fps"
<< std::endl;
start = end;
count = 0;
}
count++;
}

while (!quit) {
size_t renderBufferIndex = frameIndex % 2;
frameIndex++;

// Update the context so we get our callbacks called and
// update tracker state.
context.update();

if ((OSVR_RETURN_SUCCESS != osvrRenderManagerGetRenderInfoCollection(
render, renderParams, &renderInfoCollection))) {
std::cerr << "Could not get render info" << std::endl;
osvrDestroyRenderManager(render);
return 105;
}
osvrRenderManagerGetNumRenderInfoInCollection(renderInfoCollection, &numRenderInfo);


renderInfo.clear();
for (OSVR_RenderInfoCount i = 0; i < numRenderInfo; i++) {
OSVR_RenderInfoD3D11 info;
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerGetRenderInfoFromCollectionD3D11(
renderInfoCollection, i, &info))) {
std::cerr << "Could not get render info " << i
<< std::endl;
osvrDestroyRenderManager(render);
return 106;
}
renderInfo.push_back(info);
}
osvrRenderManagerReleaseRenderInfoCollection(renderInfoCollection);

// Set up to render to the textures for this eye
auto renderTargetView = renderBuffers[renderBufferIndex].colorBufferView;
auto depthStencilView = depthStencilViews[renderBufferIndex];
auto context = renderInfo[0].library.context;
context->OMSetRenderTargets(1, &renderTargetView, depthStencilView);

// Set up the viewport we're going to draw into.
//CD3D11_VIEWPORT viewport(static_cast<float>(renderInfo.viewport.left),
// static_cast<float>(renderInfo.viewport.lower),
// static_cast<float>(renderInfo.viewport.width),
// static_cast<float>(renderInfo.viewport.height));
CD3D11_VIEWPORT viewport(
0.0f,
0.0f,
static_cast<float>(width),
static_cast<float>(height));

context->RSSetViewports(1, &viewport);

// Make a grey background
FLOAT colorRgba[4] = { 0.3f, 0.3f, 0.3f, 1.0f };
context->ClearRenderTargetView(renderTargetView, colorRgba);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there are two windows for the two eyes, we're going to have to clear both of them here, not just one of them.

context->ClearDepthStencilView(
depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

// Render into each buffer using the specified information.
for (size_t i = 0; i < renderInfo.size(); i++) {
renderInfo[i].library.context->OMSetDepthStencilState(
depthStencilState, 1);
RenderView(i, renderInfo[i], renderTargetView, depthStencilView);
}

// Every other second, we show a black screen to test how
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code to do the black swap was removed, but this comment was not.

// a game engine might blank it between scenes. Every even
// second, we display the video.
end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_sec = end - start;
int secs = static_cast<int>(elapsed_sec.count());

// Send the rendered results to the screen
OSVR_RenderManagerPresentState presentState;
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerStartPresentRenderBuffers(&presentState))) {
std::cerr << "Could not start presenting render buffers" << std::endl;
osvrDestroyRenderManager(render);
return 201;
}

for (size_t i = 0; i < numRenderInfo; i++) {
OSVR_ViewportDescription normalizedViewport;
normalizedViewport.left = i == 0 ? 0 : 0.5;
normalizedViewport.lower = 0;
normalizedViewport.width = 0.5;
normalizedViewport.height = 1.0;

if ((OSVR_RETURN_SUCCESS != osvrRenderManagerPresentRenderBufferD3D11(
presentState, renderBuffers[renderBufferIndex], renderInfo[i], normalizedViewport))) {
std::cerr << "Could not present render buffer " << i << std::endl;
osvrDestroyRenderManager(render);
return 202;
}
}
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerFinishPresentRenderBuffers(
render, presentState, renderParams, false))) {
std::cerr << "Could not finish presenting render buffers" << std::endl;
osvrDestroyRenderManager(render);
return 203;
}

// Timing information
if (elapsed_sec.count() >= 2) {
std::chrono::duration<double, std::micro> elapsed_usec = end - start;
double usec = elapsed_usec.count();
std::cout << "Rendering at " << count / (usec * 1e-6) << " fps"
<< std::endl;
start = end;
count = 0;
}
count++;
}
// Clean up after ourselves.
// @todo

Expand Down
Loading