1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// cglmtex.h
// GLMgr textures
//
//===============================================================================
#ifndef CGLMTEX_H
#define CGLMTEX_H
#pragma once
#include "tier1/utlhash.h"
#include "tier1/utlmap.h"
//===============================================================================
// forward declarations
class GLMContext;
class GLMTester;
class CGLMTexLayoutTable;
class CGLMTex;
class CGLMFBO;
class IDirect3DSurface9;
//===============================================================================
struct GLMTexFormatDesc
{
char *m_formatSummary; // for debug visibility
D3DFORMAT m_d3dFormat; // what D3D knows it as; see public/bitmap/imageformat.h
GLenum m_glIntFormat; // GL internal format
GLenum m_glIntFormatSRGB; // internal format if SRGB flavor
GLenum m_glDataFormat; // GL data format
GLenum m_glDataType; // GL data type
int m_chunkSize; // 1 or 4 - 4 is used for compressed textures
int m_bytesPerSquareChunk; // how many bytes for the smallest quantum (m_chunkSize x m_chunkSize)
// this description lets us calculate size cleanly without conditional logic for compression
};
const GLMTexFormatDesc *GetFormatDesc( D3DFORMAT format );
//===============================================================================
// utility function for generating slabs of texels. mostly for test.
typedef struct
{
// in
D3DFORMAT m_format;
void *m_dest; // dest address
int m_chunkCount; // square chunk count (single texels or compressed blocks)
int m_byteCountLimit; // caller expectation of max number of bytes to write out
float r,g,b,a; // color desired
// out
int m_bytesWritten;
} GLMGenTexelParams;
// return true if successful
bool GLMGenTexels( GLMGenTexelParams *params );
//===============================================================================
struct GLMTexLayoutSlice
{
int m_xSize,m_ySize,m_zSize; //texel dimensions of this slice
int m_storageOffset; //where in the storage slab does this slice live
int m_storageSize; //how much storage does this slice occupy
};
enum EGLMTexFlags
{
kGLMTexMipped = 0x01,
kGLMTexMippedAuto = 0x02,
kGLMTexRenderable = 0x04,
kGLMTexIsStencil = 0x08,
kGLMTexIsDepth = 0x10,
kGLMTexSRGB = 0x20,
kGLMTexMultisampled = 0x40, // has an RBO backing it. Cannot combine with Mipped, MippedAuto. One slice maximum, only targeting GL_TEXTURE_2D.
// actually not 100% positive on the mipmapping, the RBO itself can't be mipped, but the resulting texture could
// have mipmaps generated.
};
//===============================================================================
struct GLMTexLayoutKey
{
// input values: held const, these are the hash key for the form map
GLenum m_texGLTarget; // flavor of texture: GL_TEXTURE_2D, GL_TEXTURE_3D, GLTEXTURE_CUBE_MAP
D3DFORMAT m_texFormat; // D3D texel format
unsigned long m_texFlags; // mipped, autogen mips, render target, ... ?
unsigned long m_texSamples; // zero for a plain tex, 2/4/6/8 for "MSAA tex" (RBO backed)
int m_xSize,m_ySize,m_zSize; // size of base mip
};
bool LessFunc_GLMTexLayoutKey( const GLMTexLayoutKey &a, const GLMTexLayoutKey &b );
#define GLM_TEX_MAX_MIPS 14
#define GLM_TEX_MAX_FACES 6
#define GLM_TEX_MAX_SLICES (GLM_TEX_MAX_MIPS * GLM_TEX_MAX_FACES)
struct GLMTexLayout
{
char *m_layoutSummary; // for debug visibility
// const inputs used for hashing
GLMTexLayoutKey m_key;
// refcount
int m_refCount;
// derived values:
GLMTexFormatDesc *m_format; // format specific info
int m_mipCount; // derived by starying at base size and working down towards 1x1
int m_faceCount; // 1 for 2d/3d, 6 for cubemap
int m_sliceCount; // product of faces and mips
int m_storageTotalSize; // size of storage slab required
// slice array
GLMTexLayoutSlice m_slices[0]; // dynamically allocated 2-d array [faces][mips]
};
class CGLMTexLayoutTable
{
public:
CGLMTexLayoutTable();
GLMTexLayout *NewLayoutRef( GLMTexLayoutKey *key ); // pass in a pointer to layout key - receive ptr to completed layout
void DelLayoutRef( GLMTexLayout *layout ); // pass in pointer to completed layout. refcount is dropped.
void DumpStats( void );
protected:
CUtlMap< GLMTexLayoutKey, GLMTexLayout* > m_layoutMap;
};
//===============================================================================
// a sampler specifies desired state for drawing on a given sampler index
// this is the combination of a texture choice and a set of sampler parameters
// see http://msdn.microsoft.com/en-us/library/bb172602(VS.85).aspx
struct GLMTexSamplingParams
{
GLenum m_addressModes[3]; // S, T, R
GLfloat m_borderColor[4]; // R,G,B,A
GLenum m_magFilter;
GLenum m_minFilter;
GLfloat m_mipmapBias;
GLint m_minMipLevel;
GLint m_maxMipLevel;
GLint m_maxAniso;
GLenum m_compareMode; // only used for depth and stencil type textures
bool m_srgb; // srgb texture read...
};
struct GLMTexLockParams
{
// input params which identify the slice of interest
CGLMTex *m_tex;
int m_face;
int m_mip;
// identifies the region of the slice
GLMRegion m_region;
// tells GLM to force re-read of the texels back from GL
// i.e. "I know I stepped on those texels with a draw or blit - the GLM copy is stale"
bool m_readback;
};
struct GLMTexLockDesc
{
GLMTexLockParams m_req; // form of the lock request
bool m_active; // set true at lock time. cleared at unlock time.
int m_sliceIndex; // which slice in the layout
int m_sliceBaseOffset; // where is that in the texture data
int m_sliceRegionOffset; // offset to the start (lowest address corner) of the region requested
};
//===============================================================================
#define GLM_SAMPLER_COUNT 16
typedef CBitVec<GLM_SAMPLER_COUNT> CTexBindMask;
enum EGLMTexSliceFlag
{
kSliceValid = 0x01, // slice has been teximage'd in whole at least once - set to 0 initially
kSliceStorageValid = 0x02, // if backing store is available, this slice's data is a valid copy - set to 0 initially
kSliceLocked = 0x04, // are one or more locks outstanding on this slice
kSliceFullyDirty = 0x08, // does the slice need to be fully downloaded at unlock time (disregard dirty rects)
};
class CGLMTex
{
public:
void Lock( GLMTexLockParams *params, char** addressOut, int* yStrideOut, int *zStrideOut );
void Unlock( GLMTexLockParams *params );
protected:
friend class GLMContext; // only GLMContext can make CGLMTex objects
friend class GLMTester;
friend class CGLMFBO;
friend class IDirect3DDevice9;
friend class IDirect3DBaseTexture9;
friend class IDirect3DTexture9;
friend class IDirect3DSurface9;
friend class IDirect3DCubeTexture9;
friend class IDirect3DVolumeTexture9;
CGLMTex( GLMContext *ctx, GLMTexLayout *layout, GLMTexSamplingParams *sampling, char *debugLabel = NULL );
~CGLMTex( );
int CalcSliceIndex( int face, int mip );
void CalcTexelDataOffsetAndStrides( int sliceIndex, int x, int y, int z, int *offsetOut, int *yStrideOut, int *zStrideOut );
void ApplySamplingParams( GLMTexSamplingParams *params, bool noCheck=FALSE );
void ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice=true );
void WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice=true, bool noDataWrite=false );
// last param lets us send NULL data ptr (only legal with uncompressed formats, beware)
// this helps out ResetSRGB.
void ResetSRGB( bool srgb, bool noDataWrite );
// re-specify texture format to match desired sRGB form
// noWrite means send NULL for texel source addresses instead of actual data - ideal for RT's
GLMTexLayout *m_layout; // layout of texture (shared across all tex with same layout)
int m_minActiveMip;//index of lowest mip that has been written. used to drive setting of GL_TEXTURE_MAX_LEVEL.
int m_maxActiveMip;//index of highest mip that has been written. used to drive setting of GL_TEXTURE_MAX_LEVEL.
GLMTexSamplingParams m_sampling; // mirror of sampling params currently embodied in the texture
// (consult this at draw time, in order to know if changes need to be made)
GLMContext *m_ctx; // link back to parent context
GLuint m_texName; // name of this texture in the context
bool m_texClientStorage; // was CS selecetd for texture
bool m_texPreloaded; // has it been kicked into VRAM with GLMContext::PreloadTex yet
GLuint m_rboName; // name of MSAA RBO backing the tex if MSAA enabled (or zero)
bool m_rboDirty; // has RBO been drawn on - i.e. needs to be blitted back to texture if texture is going to be sampled from
CTexBindMask m_bindPoints; // true for each place in the parent ctx where currently
// bound (indexed via EGLMTexCtxBindingIndex)
int m_rtAttachCount; // how many RT's have this texture attached somewhere
char *m_backing; // backing storage if available
int m_lockCount; // lock reqs are stored in the GLMContext for tracking
CUtlVector<unsigned char> m_sliceFlags;
char *m_debugLabel; // strdup() of debugLabel passed in, or NULL
};
#endif
|