0% found this document useful (0 votes)
41 views35 pages

DX8 Overview

Uploaded by

Willam Turner
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
41 views35 pages

DX8 Overview

Uploaded by

Willam Turner
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 35

DirectX 8 Graphics Overview

Dave Horne
Technical Developer Relations
NVIDIA Corporation
Initialisation Changes

• Merged DirectDraw and Direct3D


• Simplified API
• Improved data allocation and performance
• Promoting overall robustness
• App code simplification
• Fewer test paths

NVIDIA Proprietary and Confidential


Simplified API

• Don't need to use QueryInterfaces, and no GUIDs


in DirectX 8
• One line global D3D object creation
• m_pD3D = Direct3DCreate8(D3D_SDK_VERSION);
• D3D_SDK_VERSION ensures compilation with
correct headers
• No more callbacks!
• Query Adapters(physical pieces of hardware),
devices and modes directly from D3D object
• GetDeviceCaps() replaces GetCaps()
• called from D3D object
• No need to create devices to determine caps

NVIDIA Proprietary and Confidential


Device Types

• HAL device
• Supports hardware accelerated rasterization and
both hardware and software vertex processing
• Reference device
• Supports all features of API correctly (if not
quickly!) in software only. Intended for feature
testing, demos, etc, not for retail apps
• Software device
• DX8 supports ‘pluggable’ software devices (DDK)
• MS will not be providing a SW device
• HAL or REF device variant : Pure device
• Hardware only vertex processing
• Highly restricted querying of device state
• Performance advantage over non-pure devices
NVIDIA Proprietary and Confidential
Device Creation I

• Set ‘Presentation Parameters’ structure


• Creation of back buffer(s)
• Width, height and bit depth for full-screen
• Windowed/Full-screen
• Specifying buffer ‘Swap’ type
• Flip or Copy(Blit)
• Choose auto depth/stencil creation
• Multi-sample type
• Anti-aliasing, etc
• Full-screen refresh rate
• Can set 0 for some parameters to get default
• Set D3DPRESENTFLAG_LOCKABLE_BACKBUFFER if
you need access to the back buffer
• Setting this flag will reduce performance
NVIDIA Proprietary and Confidential
Device Creation II

• Presentation parameters structure very similar


for windowed and full-screen device creation
• Also used in device Reset() from lost device
• Behaviour flags in CreateDevice()
• D3DCREATE_*_VERTEXPROCESSING
• Software, Hardware or Mixed
• D3DCREATE_FPU_PRESERVE
• D3DCREATE_MULTITHREADED
• D3DCREATE_PUREDEVICE
• Limited renderstate shadowing
• Hardware vertex processing only

NVIDIA Proprietary and Confidential


Device Creation III
D3DPRESENT_PARAMETERS d3dpp;
memset(&d3dpp, 0, sizeof(d3dpp));

d3dpp.BackBufferWidth = 1024; // must be 0 in windowed mode


d3dpp.BackBufferHeight = 768; // must be 0 in windowed mode
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.Windowed = FALSE;
d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D32;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.hDeviceWindow = g_hwnd;

/* Following elements must be zero for Windowed mode */


d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;

pEnum->CreateDevice(
D3DADAPTER_DEFAULT, // iAdapter
D3DDEVTYPE_HAL, // device type
hWindow, // focus
D3DCREATE_FPU_PRESERVE, // dwBehaviorFlags
&d3dpp, // presentation parameters
&pDevice); // [out] pDevice

NVIDIA Proprietary and Confidential


Lost Devices I

• Supercedes DX7 Lost Surfaces


• Device can be in an operational or a lost state
• Lost state caused by loss of focus, Alt-Tab, power
management events, etc.
• Once in lost state only error returns are from
• Present()
• TestCooperativeLevel()
• All other methods succeed
• Even if they don’t do anything

NVIDIA Proprietary and Confidential


Lost Devices II

• App needs to detect and respond to Lost device


• Rendering surfaces are gone
• All unmanaged video/agp mem resources are invalid
• includes VBs and Index buffers as well as textures
• All HW states, lights and shaders are invalid
• Rebuild the device using the Reset() command
• App MUST free all unmanaged video/agp resources
• Use same presentation params as CreateDevice()

• App must recreate any unmanaged resources, as


well as renderstates, lights and shaders

NVIDIA Proprietary and Confidential


Lost Devices III
// Test the cooperative level to see if it's okay to render
// Call once per render loop
if(FAILED(hr = m_pD3DDevice->TestCooperativeLevel()))
{
// If the device was lost, do not render until we get it back
if(D3DERR_DEVICELOST == hr) return S_OK;
// Check if the device is ready to be reset
if(D3DERR_DEVICENOTRESET == hr)
{
// Call app specific non-d3d managed resource destruction
DestroyAppManagedResources();
// Resize the device
if(FAILED(hr = m_pD3DDevice->Reset(&m_d3dpp))) return hr;
// Call app specific non-d3d managed resource creation
CreateAppManagedResources();
// Restore renderstates, lights, shaders, etc.
RestoreOtherStuff();
}
return hr;
}

NVIDIA Proprietary and Confidential


Resources
• Unified resource manager
• Geometry
• Vertex buffers
• Index buffers
• Textures
• 2D Textures
• Volume textures
• Cube maps (CubeTexture)

NVIDIA Proprietary and Confidential


Resource Creation I

• Explicit types
• CreateVolumeTexture() distinct from
CreateCubeTexture(), CreateTexture()
• No CreateSurface(),GetAttachedSurface()
• Pool
• D3DPOOL_DEFAULT
• Placed in memory type based on device and usage
• Always lost on device loss
• D3DPOOL_SYSTEMMEM
• Placed in sys mem.
• Never lost
• D3DPOOL_MANAGED
• Managed by D3D or driver.
• Never lost
• Can't use with D3DUSAGE_DYNAMIC flag
NVIDIA Proprietary and Confidential
Resource Creation II

• Usage
• D3DUSAGE_DEPTHSTENCIL, D3DUSAGE_RENDERTARGET
• Indicates using as depth/stencil or render target
• D3DUSAGE_SOFTWAREPROCESSING
• D3DUSAGE_DONOTCLIP
• D3DUSAGE_DYNAMIC, D3DUSAGE_WRITEONLY
• Allows driver to place resource in optimal location
• VB only ‘hints’ to allow the driver to put VB in CPU
accessible memory if no native HW support
• D3DUSAGE_POINTS
• Point sprites
• D3DUSAGE_RTPATCHES
• 'RT' stands for rectangular and triangular high order surfaces
• D3DUSAGE_NPATCHES

NVIDIA Proprietary and Confidential


Resource Creation III

• Format
• Now an enumerated type
• Runtime predefines several types of each class
• Color, luminance, DXTn, vertex, index, etc
• IHVs may still add vendor specific formats via the
FOURCC codes
• Always allocate all D3DPOOL_DEFAULT resources
before D3DPOOL_MANAGED
• Otherwise D3D resource manager will get an
inaccurate picture of available memory

NVIDIA Proprietary and Confidential


DX8 Vertex Buffer Changes I

• Vertex buffers are now the standard usage for


DrawPrimitive()and DrawIndexedPrimitive()
• ‘User Pointer’ calls for apps that can’t use VBs for
some reason
• DrawPrimitiveUP()
• DrawIndexedPrimitiveUP()
• Don’t use! Will almost certainly result in a redundant
copy of vertex data by driver
• VBs can consist of arbitrary data in multiple streams
• Use Vertex Shaders to interpret data

NVIDIA Proprietary and Confidential


DX8 Vertex Buffer Changes II

• CreateVertexBuffer() changes
• Size now defined as number of bytes
• DX7 defined it as number of vertices
• Usage flags
• FVF code can be zero
• Called a Non-FVF VB
• Represents VB stream for vertex shader
• Format implied by CreateVertexShader() declaration
• Must declare which memory pool required
• No more maximum VB size
• DX7 max size is 0xffff

NVIDIA Proprietary and Confidential


Index Buffers I

• New resource type for DX8


• Removes redundant driver copy of indices in the
same way VBs stop driver copy of vertices
• CreateIndexBuffer() size, usage and pool
parameters the same as VB create
• Format parameter allows creation of either 16 or 32
bit indices
• D3DFMT_INDEX16, D3DFMT_INDEX32
• 32 bit indices new to DX8

NVIDIA Proprietary and Confidential


Index Buffers II

• Semantics the same as for VBs


• Create
• Lock()
• Fill
• Unlock()
• Use
• Indices now explicitly set via SetIndices()
• In DX7 they were part of the DP/DIP calls
• 'User Pointer' calls still require explicit index
parameters
• Similar to DX7
• Currently set IB is ignored
• Reminder: Don't use User Pointers!

NVIDIA Proprietary and Confidential


Locking Resources I

• Grants CPU access to resource


• Texture locks
• LockRect() for 2D textures and cube maps
• LockBox() for volume textures
• Typically only one lock per resource
• Geometry locks
• Lock() for both index and vertex buffers
• Multiple locks per buffer allowed
• Must relinquish lock with UnLock() before
resource can be used by device
• Any device operations with locked resource will
be serialised until resource unlocked
NVIDIA Proprietary and Confidential
Locking Resources II

• General lock flags


• D3DLOCK_READONLY
• Won’t write to resource so no recompression on unlock
• Can’t use with VBs/IBs created with WRITEONLY flag
• D3DLOCK_NOSYSLOCK
• No system-wide critical section taken
• Texture specific lock flags
• D3DLOCK_NO_DIRTY_UPDATE
• Don’t update dirty region
• Geometry specific lock flags
• D3DLOCK_DISCARD
• D3DLOCK_NOOVERWRITE

NVIDIA Proprietary and Confidential


Locking Textures I

• LockRect() can lock whole surface or sub-rect


of 2D texture or face of cube map
• Lock with RECT or NULL for entire surface
• Returns D3DLOCKED_RECT
• Consists of data pointer and pitch (in bytes)
• Simpler than DX7 surface lock return
DDSURFACEDESC2
• Must specify mip level required for lock
• Cube textures must also specify face

NVIDIA Proprietary and Confidential


Locking Textures II

• Use LockBox() for to lock volume or sub-


volume of 3D texture
• Lock with D3DBOX structure or NULL for entire
volume
• Must also specify mip level
• All 3 dimensions of each level are divided by 2
(rounding down) down to minimum 1x1x1
• Returns D3DLOCKED_BOX
• Consists of data pointer, row pitch and slice pitch
• Compressed DXT formats
• Can only be locked on 4x4 boundaries
• Minimum actual size is 4x4 on a side
• Textures or mip levels less than this are padded
NVIDIA Proprietary and Confidential
Locking Geometry

• DX8 Lock() on VBs and IBs allows sub-ranges to


be specified
• DX7 could only lock whole VB
• Multiple locks on single buffer permitted
• Allows efficient usage of large VBs containing
multiple models, as you can render from one sub
range whilst locking and modifying another
• D3DLOCK_DISCARD and D3DLOCK_NOOVERWRITE
flags are valid only on buffers created with
D3DUSAGE_DYNAMIC
• Therefore can't be managed buffers

NVIDIA Proprietary and Confidential


Programmable Vertex Shaders

• New feature for DX8


• Can be used in place of D3D 'fixed function' T&L
pipeline
• Allows extremely versatile geometry handling by
using vertex programs to process vertex data
• Operates at the vertex level only
• No knowledge of other vertices (no primitives)
• Cannot create or destroy vertices
• Vertex output must be in homogenous clip-space
with colour, texture coordinate, fog, and sprite
point size as needed
NVIDIA Proprietary and Confidential
Streams

• New for DX8


• Allows multiple VBs to be set as data sources for
vertex processing
• Stream elements are combined at draw time
• Single set of indices for all streams in DX8
• GeForce/GeForce2 can support up to 8 vertex
streams, fed to the fixed-function T&L pipeline
only
• DX8 level hardware must be able to support up to
16 vertex streams, fed to the fixed-function OR
vertex shading pipeline
NVIDIA Proprietary and Confidential
Creating Vertex Shaders

• Use CreateVertexShader()
• Pass in a declaration defining input to shader
• Define format of vertex streams and bindings to vertex
shader input registers
• Bind primitive tessellator to input registers
• Loading of data into constant memory
• Pass in pointer to vertex shader program token data
• E.g. from D3DXAssembleShader
• Or use NULL to get fixed function processing
• Usage flag
• D3DUSAGE_SOFTWAREPROCESSING if you're using
software vertex processing
• Returns handle for use in SetVertexShader()

NVIDIA Proprietary and Confidential


Setting Streams

• Call SetStreamSource()
• Stream index
• 0 to (maximum number of streams - 1)
• Pointer to VB
• Stride of vertex
• For FVF VBs must be the size of vertex computed
from FVF code
• For non-FVF VBs must match the size implied in the
CreateVertexShader() declaration
• Number and format of streams set must match
the current vertex shader declaration

NVIDIA Proprietary and Confidential


Using Vertex Shaders

• Ensure that all VB streams have been set


• Set an IB with SetIndices() if using indexed data
• Use SetVertexShader() to select shader
• Pass in a handle from CreateVertexShader()
• Or pass a valid FVF code to use the fixed function
pipeline
• Use DrawPrimitive() or DrawIndexedPrimitive()
to render primitives

NVIDIA Proprietary and Confidential


Fixed Function Pipeline

• Can use the existing 'fixed function' T&L pipeline


with standard flexible vertex format codes
• Use SetVertexShader() with an FVF code instead
of a vertex shader handle
• Only stream 0 is valid
• Example pseudocode
gVB = CreateVertexBuffer(); // with FVF code
// Lock, fill, unlock gVB
SetVertexShader(); // with same FVF code
SetStreamSource(0, gVB, sizeof(Vertex));
DrawPrimitive();
NVIDIA Proprietary and Confidential
Fixed Function - Multiple Streams
• Create and set a vertex shader with declarator
describing streams, and NULL program
• Create VBs for each of the separate streams, and set
them as stream sources
• Pseudocode for a 2 stream XYZ and colour multiple
stream fixed function shader
hVS = CreateVertexShader(pDec, NULL,...);
gVB_Pos = CreateVertexBuffer(FVFXYZ);
gVB_Col = CreateVertexBuffer(FVFCOLOR);
SetVertexShader(hVS);
SetStreamSource(0, gVB_Pos, sizeof(XYZ));
SetStreamSource(1, gVB_Col, sizeof(COLOR));
DrawPrimitive();

NVIDIA Proprietary and Confidential


Scene Presentation

• New device function Present()


• Subsumes DX7 Flip() and Blit()
• Consistent for full-screen and windowed
• Simplifies renderloop
• No more windowed app lag due to excessive blit
buffering
• Swap chain now a property of device
• Number of buffers specified in device creation
• Always at least one chain
• Additional ones can be created if needed
• Front buffer now part of device
NVIDIA Proprietary and Confidential
Front Buffer

• No more concept of ‘Primary Surface’


• Front buffer not directly accessible
• Cannot lock or render to
• Mouse cursor API available
• Hardware if available
• Can get to front buffer via GetFrontBuffer()
• Guaranteed to be slow
• Only really useful for debugging

NVIDIA Proprietary and Confidential


Depth/Stencil Surfaces

• Z buffer now set into the device


• AutoDepthStencil
• Set in presentation params – created, destroyed and
resized automatically by the device
• Explicit DepthStencil creation
• Created by app, and attached to the device
• Use SetRenderTarget()
• Useful when switching render targets halfway
through a scene
• No auto resize on mode or window size changes
• No auto destruction

NVIDIA Proprietary and Confidential


Reset() (again)

• As well as responding to lost devices, Reset()


can be used to
• Resize the buffers
• Change buffer format
• Swap between full-screen and windowed
• Switch stereo on and off
• Calling Reset() causes all unmanaged video/agp
memory resources, and all state information, to
be lost.
• So similar (if not identical) code path to recovery
from device loss

NVIDIA Proprietary and Confidential


Summary

• DX8 initialisation is far easier than DX7


• Device creation and loss management improved
• New Index Buffer resource gives VB style
management for indices
• Vertex streams allows vertex components in
separate VBs
• Vertex shaders will give unprecedented
programmability in the transform pipeline
• Scene presentation simplified

NVIDIA Proprietary and Confidential

You might also like