aboutsummaryrefslogtreecommitdiff
path: root/sp/src/public/togl/osx/cglmtex.h
blob: 813395c7650c9c3be3c7cb5f3efaf2b763b67da7 (plain) (blame)
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