1 /*
2  *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
3  *
4  *  File: d3dmacs.h
5  *
6  *  Useful macros for generating execute buffers.  Consult the D3D sample
7  *  code for examples of their usage.
8  *
9  *  Use OP_NOP to QWORD align triangle and line instructions.
10  */
11 
12 #ifndef __D3DMACS_H__
13 #define __D3DMACS_H__
14 
15 #undef RELEASE
16 
17 #ifndef __cplusplus
18 #define MAKE_MATRIX(lpDev, handle, data) \
19     if (lpDev->lpVtbl->CreateMatrix(lpDev, &handle) != D3D_OK) \
20         return FALSE; \
21     if (lpDev->lpVtbl->SetMatrix(lpDev, handle, &data) != D3D_OK) \
22         return FALSE
23 #define RELEASE(x) if (x != NULL) {x->lpVtbl->Release(x); x = NULL;}
24 #endif
25 
26 #ifdef __cplusplus
27 #define MAKE_MATRIX(lpDev, handle, data) \
28     if (lpDev->CreateMatrix(&handle) != D3D_OK) \
29         return FALSE; \
30     if (lpDev->SetMatrix(handle, &data) != D3D_OK) \
31         return FALSE
32 #define RELEASE(x) if (x != NULL) {x->Release(); x = NULL;}
33 #endif
34 
35 #define PUTD3DINSTRUCTION(op, sz, cnt, ptr) \
36     ((LPD3DINSTRUCTION) ptr)->bOpcode = op; \
37     ((LPD3DINSTRUCTION) ptr)->bSize = sz; \
38     ((LPD3DINSTRUCTION) ptr)->wCount = cnt; \
39     ptr = (void *)(((LPD3DINSTRUCTION) ptr) + 1)
40 
41 #define VERTEX_DATA(loc, cnt, ptr) \
42     if ((ptr) != (loc)) memcpy((ptr), (loc), sizeof(D3DVERTEX) * (cnt)); \
43     ptr = (void *)(((LPD3DVERTEX) (ptr)) + (cnt))
44 
45 // OP_MATRIX_MULTIPLY size: 4 (sizeof D3DINSTRUCTION)
46 #define OP_MATRIX_MULTIPLY(cnt, ptr) \
47     PUTD3DINSTRUCTION(D3DOP_MATRIXMULTIPLY, sizeof(D3DMATRIXMULTIPLY), cnt, ptr)
48 
49 // MATRIX_MULTIPLY_DATA size: 12 (sizeof MATRIXMULTIPLY)
50 #define MATRIX_MULTIPLY_DATA(src1, src2, dest, ptr) \
51     ((LPD3DMATRIXMULTIPLY) ptr)->hSrcMatrix1 = src1; \
52     ((LPD3DMATRIXMULTIPLY) ptr)->hSrcMatrix2 = src2; \
53     ((LPD3DMATRIXMULTIPLY) ptr)->hDestMatrix = dest; \
54     ptr = (void *)(((LPD3DMATRIXMULTIPLY) ptr) + 1)
55 
56 // OP_STATE_LIGHT size: 4 (sizeof D3DINSTRUCTION)
57 #define OP_STATE_LIGHT(cnt, ptr) \
58     PUTD3DINSTRUCTION(D3DOP_STATELIGHT, sizeof(D3DSTATE), cnt, ptr)
59 
60 // OP_STATE_TRANSFORM size: 4 (sizeof D3DINSTRUCTION)
61 #define OP_STATE_TRANSFORM(cnt, ptr) \
62     PUTD3DINSTRUCTION(D3DOP_STATETRANSFORM, sizeof(D3DSTATE), cnt, ptr)
63 
64 // OP_STATE_RENDER size: 4 (sizeof D3DINSTRUCTION)
65 #define OP_STATE_RENDER(cnt, ptr) \
66     PUTD3DINSTRUCTION(D3DOP_STATERENDER, sizeof(D3DSTATE), cnt, ptr)
67 
68 // STATE_DATA size: 8 (sizeof D3DSTATE)
69 #define STATE_DATA(type, arg, ptr) \
70     ((LPD3DSTATE) ptr)->drstRenderStateType = (D3DRENDERSTATETYPE)type; \
71     ((LPD3DSTATE) ptr)->dwArg[0] = arg; \
72     ptr = (void *)(((LPD3DSTATE) ptr) + 1)
73 
74 // OP_PROCESS_VERTICES size: 4 (sizeof D3DINSTRUCTION)
75 #define OP_PROCESS_VERTICES(cnt, ptr) \
76     PUTD3DINSTRUCTION(D3DOP_PROCESSVERTICES, sizeof(D3DPROCESSVERTICES), cnt, ptr)
77 
78 // PROCESSVERTICES_DATA size: 16 (sizeof D3DPROCESSVERTICES)
79 #define PROCESSVERTICES_DATA(flgs, strt, cnt, ptr) \
80     ((LPD3DPROCESSVERTICES) ptr)->dwFlags = flgs; \
81     ((LPD3DPROCESSVERTICES) ptr)->wStart = strt; \
82     ((LPD3DPROCESSVERTICES) ptr)->wDest = strt; \
83     ((LPD3DPROCESSVERTICES) ptr)->dwCount = cnt; \
84     ((LPD3DPROCESSVERTICES) ptr)->dwReserved = 0; \
85     ptr = (void *)(((LPD3DPROCESSVERTICES) ptr) + 1)
86 
87 // OP_TRIANGLE_LIST size: 4 (sizeof D3DINSTRUCTION)
88 #define OP_TRIANGLE_LIST(cnt, ptr) \
89     PUTD3DINSTRUCTION(D3DOP_TRIANGLE, sizeof(D3DTRIANGLE), cnt, ptr)
90 
91 #define TRIANGLE_LIST_DATA(loc, count, ptr) \
92     if ((ptr) != (loc)) memcpy((ptr), (loc), sizeof(D3DTRIANGLE) * (count)); \
93     ptr = (void *)(((LPD3DTRIANGLE) (ptr)) + (count))
94 
95 // OP_LINE_LIST size: 4 (sizeof D3DINSTRUCTION)
96 #define OP_LINE_LIST(cnt, ptr) \
97     PUTD3DINSTRUCTION(D3DOP_LINE, sizeof(D3DLINE), cnt, ptr)
98 
99 #define LINE_LIST_DATA(loc, count, ptr) \
100     if ((ptr) != (loc)) memcpy((ptr), (loc), sizeof(D3DLINE) * (count)); \
101     ptr = (void *)(((LPD3DLINE) (ptr)) + (count))
102 
103 // OP_POINT_LIST size: 8 (sizeof D3DINSTRUCTION + sizeof D3DPOINT)
104 #define OP_POINT_LIST(first, cnt, ptr) \
105     PUTD3DINSTRUCTION(D3DOP_POINT, sizeof(D3DPOINT), 1, ptr); \
106     ((LPD3DPOINT)(ptr))->wCount = cnt; \
107     ((LPD3DPOINT)(ptr))->wFirst = first; \
108     ptr = (void*)(((LPD3DPOINT)(ptr)) + 1)
109 
110 // OP_SPAN_LIST size: 8 (sizeof D3DINSTRUCTION + sizeof D3DSPAN)
111 #define OP_SPAN_LIST(first, cnt, ptr) \
112     PUTD3DINSTRUCTION(D3DOP_SPAN, sizeof(D3DSPAN), 1, ptr); \
113     ((LPD3DSPAN)(ptr))->wCount = cnt; \
114     ((LPD3DSPAN)(ptr))->wFirst = first; \
115     ptr = (void*)(((LPD3DSPAN)(ptr)) + 1)
116 
117 // OP_BRANCH_FORWARD size: 18 (sizeof D3DINSTRUCTION + sizeof D3DBRANCH)
118 #define OP_BRANCH_FORWARD(tmask, tvalue, tnegate, toffset, ptr) \
119     PUTD3DINSTRUCTION(D3DOP_BRANCHFORWARD, sizeof(D3DBRANCH), 1, ptr); \
120     ((LPD3DBRANCH) ptr)->dwMask = tmask; \
121     ((LPD3DBRANCH) ptr)->dwValue = tvalue; \
122     ((LPD3DBRANCH) ptr)->bNegate = tnegate; \
123     ((LPD3DBRANCH) ptr)->dwOffset = toffset; \
124     ptr = (void *)(((LPD3DBRANCH) (ptr)) + 1)
125 
126 // OP_SET_STATUS size: 20 (sizeof D3DINSTRUCTION + sizeof D3DSTATUS)
127 #define OP_SET_STATUS(flags, status, _x1, _y1, _x2, _y2, ptr) \
128     PUTD3DINSTRUCTION(D3DOP_SETSTATUS, sizeof(D3DSTATUS), 1, ptr); \
129     ((LPD3DSTATUS)(ptr))->dwFlags = flags; \
130     ((LPD3DSTATUS)(ptr))->dwStatus = status; \
131     ((LPD3DSTATUS)(ptr))->drExtent.x1 = _x1; \
132     ((LPD3DSTATUS)(ptr))->drExtent.y1 = _y1; \
133     ((LPD3DSTATUS)(ptr))->drExtent.x2 = _x2; \
134     ((LPD3DSTATUS)(ptr))->drExtent.y2 = _y2; \
135     ptr = (void *)(((LPD3DSTATUS) (ptr)) + 1)
136 
137 // OP_NOP size: 4
138 #define OP_NOP(ptr) \
139     PUTD3DINSTRUCTION(D3DOP_TRIANGLE, sizeof(D3DTRIANGLE), 0, ptr)
140 
141 #define OP_EXIT(ptr) \
142     PUTD3DINSTRUCTION(D3DOP_EXIT, 0, 0, ptr)
143 
144 #define QWORD_ALIGNED(ptr) \
145     !(0x00000007L & (ULONG)(ptr))
146 
147 #endif // __D3DMACS_H__
148