Basically after posting on the DX12 wishlist thread an idea I got overnight, I spent more time on the design, it's not fundamentally different but there are a few more explanations about it.
Here are an extended version ideas:
I haven't written an application using this API yet (it wouldn't do anything anyway as it's not implemented), but I plan to in order to make sure nothing's missing.
I'd be curious to hear about other programmers ideas, and how well they think it would integrate into their engine(s), and whether it would make their lives easier...
Code:
Have ZERO validation during rendering by using a Pipeline object encompassing ALL states. (but no pointer to buffers/textures)
Fetching an invalid (not COMMITed) page returns zero.
/* STANDARD VERSION */
Device
{
/* EVENT */
HEvent CreateEvent();
void WaitForEvent( HEvent );
void WaitForMultipleEvents( HEvent[], count );
/* DATA */
void* MemAlloc( CPU|GPU, size, RESERVE&|COMMIT ); //c.f. VirtualAlloc
void MemFree( address, size, RELEASE|DECOMMIT ); //c.f. VirtualFree
Descriptor* CreateBufferDesc( address, size/*, DXGI_FORMAT[], count*/ ); //{Index/Vertex/Constant/Texture}Buffer ; For DEBUG it might be useful to type buffers too.
// Surfaces need a complex Descriptor because data is transformed from CPU memory to GPU memory... (Morten Order...) ; In the case of std layouts + restrictions it wouldn't need be
Descriptor* CreateSurfaceDesc( address, {1D, 2D, 3D, CUBE}, DXGI_FORMAT, samples, width, height, depth, /*layers,*/ lod ); //reinterpret width/height/depth, add layers if 3D_ARRAY allowed
/* PROGRAM/PIPELINE */
Program* CreateProgram( {Vertex, [ Hull, Tessellator², Domain, ] Geometry, Rasterizer², Fragment, DepthStencil², Blender²}, char* source );
// All items marked with "²" are states.
// Samplers are also states defined in their respective programs, and include a DXGI_FORMAT.
// Vertex Programs include the index DXGI_FORMAT, vertex buffer descriptions (inc. DXGI_FORMAT) and IB & VB[] "bindings". (For PipelineProgramDescriptors)
// Fragment Programs include all output buffers making the FrameBuffer.
Pipeline* CreatePipeline( Program[], count ); //That's the whole graphics pipeline in one object.
/* COMMAND QUEUE */
CommandQueue* CreateCommandQueue();
void Process( CommandQueue& queue ); // FIFO order queuing then execution.
/* DISPLAY */
void Show( Descriptor left, Descriptor* right, iRefresh ); //right is optional for stereoscopy. iRefresh : at which screen refresh to display it. (0=immediatly, 1=next... ; -1=next unless late already in which case immediatly)
// It does not work on a multi sampled Surface.
}
CommandQueue
{
//Every function in here is added to the CommandQueue and doesn't execute until the CommandQueue runs after having been enqueued on the Device.
/* EVENT */
void Insert( HEvent );
/* MEMORY */
void MemSet( address, size, value );
void MemCopy( src, dst, size );
void MemCopyEx( src, dst, size, DXGI_FORMAT ); // When src is CPUmem, data is linear. When dst is GPUmem it will be optimised to native [Textures]. => src@GPUmem & dst@CPUmem means data will be turned into linear.
/* PIPELINE SETUP */
void Pipeline( Pipeline* );
void PipelineProgramDescriptors( Descriptor[]*, uint32_t* counts ); // 1 Descriptor[] per Pipeline's Program
// That's akin to "SetShaderResources" and "SetConstantBuffers"... functions of D3D10+, except you just provide Descriptors array for each Program.
// IB & VB[] are also set using this function. The Program specifies the array layout.
// "Framebuffer" is also specified by Descriptors
/* DRAW */
enum MODE { POINTS, LINES(_ADJ), LINE_STRIP(_ADJ), TRIANGLES(_ADJ), TRIANGLE_STRIP(_ADJ), PATCHES };
void DrawArrays( MODE, First, nVertices, nInstances, BaseInstance );
void DrawElements( MODE, First, nIndices, BaseVertex, nInstances, BaseInstance );
void DrawArraysIndirect( MODE, Descriptor ); //Buffer format : First, nVertices, nInstances, BaseInstance
void DrawElementsIndirect( MODE, Descriptor ); //Buffer format : First, nIndices, BaseVertex, nInstances, BaseInstance
// w/ First : the starting point in VB(DrawArrays), IB(DrawElements) ; BaseVertex : a constant added to each index before fetching from VB ; BaseInstance : the base instance for use in fetching instanced vertex attributes.
/* DISPATCH */
void Dispatch( nX, nY, nZ );
void DispatchIndirect( Descriptor ); //Buffer format : nX, nY, nZ
}
Shading Language: similar to CLSL I'd think.
Here are an extended version ideas:
Code:
/* EXTENDED VERSION */
Device
{
void SetPageFaultHandler( PAGEFAULTHANDLERPROC ); //Called either at each individual Page fault, or after each Show(...)
}
Shader Language:
-Needs access to existing Descriptors and Pipelines. (Optional access to existing CommandQueues ?)
-Needs CreateCommandQueue() & Process( CommandQueue& queue ).
-Needs all CommandQueue functions, except Insert( HEvent ).
I haven't written an application using this API yet (it wouldn't do anything anyway as it's not implemented), but I plan to in order to make sure nothing's missing.
I'd be curious to hear about other programmers ideas, and how well they think it would integrate into their engine(s), and whether it would make their lives easier...