Tuesday, 21 January 2014

Requirements for a modern game engine

Text-based JSON data files - for everything possible
Comprehensive error-detection in API functions
Avoid callbacks
Fast in-engine update-on-demand for data changes
Procedural as much as possible
Physics-based rendering
Effects files (fx)

Wednesday, 15 January 2014

To link properly with the FBX SDK, define FBXSDK_SHARED in C++ preprocessor options.

Thursday, 9 January 2014

Always replace Qt's sqlite code with the latest sqlite. Switching from Qt's 3.7 to 3.8.2 makes a 60-second query take 1/2 second.

Tuesday, 7 January 2014

In Qt, the sizePolicy for containers should be Expanding. That's the only policy that respects the minimum sizes of its contents. The policy "MinimumExpanding" ignores the contents and only looks at the widget's own minimum size value.

Saturday, 28 December 2013

Updating Vertex Buffers in DX11: StreamOut vs Compute

Benchmarking an update of 125,000 vertices (xyz float) using double-buffered StreamOut compared to compute with a single buffer.

The compute C++ code is:
 dx11::setUnorderedAccessView(effect,"targetVertexBuffer",vertexBuffer.unorderedAccessView);
 ApplyPass(pContext,effect->GetTechniqueByName("move_particles_compute")->GetPassByIndex(0));
 pContext->Dispatch(5,5,5);

The StreamOut C++ code is:

 pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST );
 pContext->IASetInputLayout( m_pVtxDecl );
    
 ID3D11Buffer *pBuffer;
 pBuffer    =vertexBuffer.vertexBuffer;
 UINT stride   = sizeof(vec3);
 UINT offset[1]   = { 0 };
 pContext->IASetVertexBuffers( 0, 1, &pBuffer,&stride, offset );

 // Point to the correct output buffer
 pContext->SOSetTargets( 1, &m_pVertexBufferSwap, offset );

 // draw
 D3DX11_TECHNIQUE_DESC techDesc;
 techniqueMoveParticles->GetDesc( &techDesc );
 techniqueMoveParticles->GetPassByIndex(0)->Apply(0,pContext);

 pContext->Draw(125000 , 0 );

 // Get back to normal
 pBuffer    = NULL;
 pContext->SOSetTargets( 1, &pBuffer, offset );

 // Swap buffers
 ID3D11Buffer* pTemp  = m_pVertexBufferSwap;
 m_pVertexBufferSwap  = vertexBuffer.vertexBuffer;
 vertexBuffer.vertexBuffer = pTemp;

And the results: the compute operation takes 0.014ms, the geometry shader one takes 0.16ms. But: it turns out that only StreamOut is actually updating all of the vertices. Compute updates about 8000, then silently gives up.

Turning on Debug using DirectX Control Panel, we learn that passing a vertex buffer's UAV to a shader as a structured buffer is NOT supported. So StreamOut is actually the only option here.

Tuesday, 26 November 2013

UnorderedAccessView of a vertex buffer

Here's how to create a vertex buffer that you can write with a compute shader:

D3D11_BUFFER_DESC desc =
    {
        40000*sizeof(vec3)
        ,D3D11_USAGE_DEFAULT
        ,D3D11_BIND_VERTEX_BUFFER|D3D11_BIND_UNORDERED_ACCESS
        ,0  // NoCPU access
 ,0  // not D3D11_RESOURCE_MISC_BUFFER_STRUCTURED - why?
 ,sizeof(vec3)   //StructureByteStride
 };
    m_pd3dDevice->CreateBuffer(&desc,NULL,&m_pVertexBuffer);


    D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc;
    ZeroMemory(&uav_desc, sizeof(D3D11_UNORDERED_ACCESS_VIEW_DESC));
    uav_desc.Format   =DXGI_FORMAT_R32_FLOAT;    // Must be this format, or INVALID_ARG will occur
    uav_desc.ViewDimension  =D3D11_UAV_DIMENSION_BUFFER;
    uav_desc.Buffer.NumElements  =40000;
    V_CHECK(m_pd3dDevice->CreateUnorderedAccessView(m_pVertexBuffer, &uav_desc, &unorderedAccessView));

Managed C++/CLI references

In Visual Studio, after adding a reference to a managed .dll, you need to unload the project, edit the .vcxproj, then:

1. Change the absolute to relative paths, using environment variables.
2. Remove the version information, otherwise it will refuse to recognize updates.