/*==========================================================================;
 *
 *  Copyright (C) 1995-2000 Microsoft Corporation.  All Rights Reserved.
 *
 *  File:   ddi.h
 *  Content:    Direct3D DDI encapsulation implementations
 *
 *
 ***************************************************************************/

#ifndef _DDIBASE_H
#define _DDIBASE_H

#include "d3ditype.h"
#include "d3dhalp.h"

extern char *HrToStr(HRESULT hr);

class CD3DBase;

struct _D3D8_DEVICEDATA;
typedef struct _D3D8_DEVICEDATA D3D8_DEVICEDATA;

class CSurface;
class D3DFE_PROCESSVERTICES;
class CBaseTexture;
class CDriverVertexBuffer;
struct CVStream;
struct CVIndexStream;
class CBaseSurface;
class CResource;
class CBuffer;

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
// CD3DDDI                                                                 //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
class CD3DDDI
{
protected:

    // DrawIndexedStream params
    UINT        m_StartIndex;
    UINT        m_MinVertexIndex;
    UINT        m_NumVertices;
    int         m_BaseVertexIndex;
    
public:
    CD3DDDI();
    virtual ~CD3DDDI();

    //++++++++++++++ Interface which the PSGP is using ++++++++++++++++++++++++
    //
    // These functions are used when vertices are processed by D3D pipeline.

    // Internal driver buffers
    // D3D has three driver buffers: TL buffer, which contains primitive 
    // vertices, command buffer, where drawing commands are recorded, and clip
    // buffer, where vertices, generated by clipper, are recorded. D3D maintains 
    // count of vertices in the TL buffer (TL buffer vertex count) and an index 
    // of the first vertex of the current primitive (primitive base). When a 
    // drawing command is recorded, D3D records the current primitive base.
    // All drawing commands expect that vertices have already been copied to the
    // TL buffer (excluding DrawClippedPrim).
    //
    // If a flush occurs during recording a command, vertex buffer is not 
    // flushed, because m_bWithinPrimitive is set to TRUE. So primitive base
    // and TL vertex count stay the same.
    //
    // When PSGP processes and clip a non-indexed primitive, it should update
    // primitive base and TL vertex count, using SkipVertices and 
    // MovePrimitiveBase functions. AddVertices is not used, because DrawPrim()
    // functions calls AddVertices and MovePrimitiveBase inself.

    // Draw unclipped part of non-indexed primitive
    //
    //   Parameters:
    //      pv->lpvOut          - pointer to the first vertex
    //      pv->primType        - primitiveType;                                
    //      pv->dwNumVertices   - vertexCount
    //      pv->dwNumPrimitives - number of primitives
    //  Remarks:
    //      This function is used when vertices are processed by D3D pipeline.
    //      The function inserts a new command to the command buffer.
    //      Primitive base is increased by the number of vertices.
    //      TL buffer vertex count is increased by the number of vertices.
    //
    virtual void DrawPrim(D3DFE_PROCESSVERTICES* pv)                = 0;

    // Draw unclipped part of an indexed primitive
    //
    //   Parameters:
    //      pv->lpvOut          - pointer to the first vertex of the whole
    //                            primitive
    //      pv->primType        - primitiveType                    
    //      pv->dwNumPrimitives - number of primitives
    //      pv->lpwIndices      - pointer to the first index                                     
    //      pv->dwNumIndices    - number of indices                                  
    //      pv->dwIndexSize     - size of an index in bytes (2 or 4)
    //  Remarks:
    //      Vertices must be already copied to the TL buffer.
    //      The function inserts a new command to the command buffer.
    //      Indices are copied to the index buffer. Vertices must be in the TL
    //      buffer already.
    //      Primitive base and TL buffer vertex count are not changed.
    //
    virtual void DrawIndexPrim(D3DFE_PROCESSVERTICES* pv)           = 0;
    
    // Draw a primitive, generated by clipper
    //
    //   Parameters:
    //      pv->lpvOut          - pointer to the first vertex of the primitive
    //      pv->primType        - primitiveType
    //      pv->dwNumVertices   - vertex count
    //      pv->dwNumPrimitives - number of primitives
    //  Remarks:
    //      Vertices are copied to the clipping buffer
    //      The function inserts a new command to the command buffer.
    //      Primitive base and TL buffer vertex count are not changed.
    //
    virtual void DrawClippedPrim(D3DFE_PROCESSVERTICES* pv)         = 0;

    // Increase TL buffer vertex count
    //
    //  The function addes the number of vertices to the current primitive 
    //  base. So when it is called several times without moving the primitive
    //  base, only the last call will have effect.
    //  This function should be called after vertices are added to the
    //  TL buffer, but before a drawing function is called.
    //
    virtual void AddVertices(UINT NumVertices)                      = 0;

    // Decrease TL buffer vertex count
    //
    //  This function should be called after vertices are added to the
    //  TL buffer, but before a drawing function is called.
    //
    virtual void SubVertices(UINT NumVertices)                      = 0;

    // Update primitive base
    //
    // It should be called when some vertices are skipped because of clipping.
    // NumVertices could be negative, 
    //
    virtual void MovePrimitiveBase(int NumVertices)                 = 0;

    // Update primitive base and TL buffer vertex count
    //
    // Call this function when some vertices in the vertex buffer are used
    // for clipping and should be skipped
    //
    virtual void SkipVertices(DWORD NumVertices)                    = 0;

    void SetIndexedPrimParams(UINT StartIndex, UINT MinIndex, UINT NumVertices,
                              UINT BaseVertexIndex)
    {
        m_StartIndex = StartIndex;
        m_MinVertexIndex = MinIndex;
        m_NumVertices = NumVertices;
        m_BaseVertexIndex = BaseVertexIndex;
    }
    
    // Returns offset in bytes of the start vertex of the current primitive in
    // the current TL stream
    virtual DWORD GetCurrentPrimBase() {return 0;}
    //-------------------- End PSGP functions ---------------------------------
};
typedef CD3DDDI *LPD3DDDI;


#endif /* _D3DIBASE_H */
