summaryrefslogtreecommitdiff
path: root/DevIL/src-ILUT/src/ilut_directx10.c
blob: afb00b272c4f019d636bea7eec3124eeda88723f (plain)
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
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
//-----------------------------------------------------------------------------
//
// ImageLib Utility Toolkit Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 12/17/2008
//
// Filename: src-ILUT/src/ilut_directx10.c
//
// Description: DirectX 10 functions for textures
//
//-----------------------------------------------------------------------------


// Needed to use the C interface to DirectX 10.
#define COBJMACROS

#include "ilut_internal.h"
#ifdef ILUT_USE_DIRECTX10

#include <d3d10.h>

#pragma comment(lib, "d3d10.lib")
#pragma comment(lib, "d3dx10.lib")


ILimage*	MakeD3D10Compliant(ID3D10Device *Device, DXGI_FORMAT *DestFormat);
ILenum		GetD3D10Compat(ILenum Format);
//D3DFORMAT	GetD3D10Format(ILenum Format);
D3DFORMAT	D3DGetDXTCNumDX10(ILenum DXTCFormat);
ILenum		D3DGetDXTCFormat(D3DFORMAT DXTCNum);
ILboolean	iD3D10CreateMipmaps(IDirect3DTexture9 *Texture, ILimage *Image);
//IDirect3DTexture10* iD3DMakeTexture( IDirect3DDevice9 *Device, void *Data, ILuint DLen, ILuint Width, ILuint Height, D3DFORMAT Format, D3DPOOL Pool, ILuint Levels );


#define ILUT_TEXTUREFORMAT_D3D10_COUNT		7
ILboolean	FormatsDX10Checked = IL_FALSE;
ILboolean	FormatsDX10supported[ILUT_TEXTUREFORMAT_D3D10_COUNT] =
	{ IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE, IL_FALSE };
D3DFORMAT	FormatsDX10[ILUT_TEXTUREFORMAT_D3D10_COUNT] =
{ DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_BC1_UNORM_SRGB, DXGI_FORMAT_BC3_UNORM_SRGB, DXGI_FORMAT_BC5_UNORM};


// Nothing to do at the moment
ILboolean ilutD3D10Init()
{

	return IL_TRUE;
}


void CheckFormatsDX10(ID3D10Device *Device)
{
	ILuint	i;
	UINT	FormatSupport;

	for (i = 0; i < ILUT_TEXTUREFORMAT_D3D10_COUNT; i++) {
		ID3D10Device_CheckFormatSupport(Device, FormatsDX10[i], &FormatSupport);
		FormatsDX10supported[i] = (FormatSupport & D3D10_FORMAT_SUPPORT_TEXTURE2D) ? IL_TRUE : IL_FALSE;
	}
	FormatsDX10Checked = IL_TRUE;

	return;
}

#ifndef _WIN32_WCE
ILboolean ILAPIENTRY ilutD3D10TexFromFile(ID3D10Device *Device, ILconst_string FileName, ID3D10Texture2D **Texture)
{
	iBindImageTemp();
	if (!ilLoadImage(FileName))
		return IL_FALSE;

	*Texture = ilutD3D10Texture(Device);

	return IL_TRUE;
}
#endif//_WIN32_WCE


ILboolean ILAPIENTRY ilutD3D10TexFromFileInMemory(ID3D10Device *Device, void *Lump, ILuint Size, ID3D10Texture2D **Texture)
{
	iBindImageTemp();
	if (!ilLoadL(IL_TYPE_UNKNOWN, Lump, Size))
		return IL_FALSE;

	*Texture = ilutD3D10Texture(Device);

	return IL_TRUE;
}


ILboolean ILAPIENTRY ilutD3D10TexFromResource(ID3D10Device *Device, HMODULE SrcModule, ILconst_string SrcResource, ID3D10Texture2D **Texture)
{
	HRSRC	Resource;
	ILubyte	*Data;

	iBindImageTemp();

	Resource = (HRSRC)LoadResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP));
	Data = (ILubyte*)LockResource(Resource);
	if (!ilLoadL(IL_TYPE_UNKNOWN, Data, SizeofResource(SrcModule, FindResource(SrcModule, SrcResource, RT_BITMAP))))
		return IL_FALSE;

	*Texture = ilutD3D10Texture(Device);

	return IL_TRUE;
}


ILboolean ILAPIENTRY ilutD3D10TexFromFileHandle(ID3D10Device *Device, ILHANDLE File, ID3D10Texture2D **Texture)
{
	iBindImageTemp();
	if (!ilLoadF(IL_TYPE_UNKNOWN, File))
		return IL_FALSE;

	*Texture = ilutD3D10Texture(Device);

	return IL_TRUE;
}


D3DFORMAT D3DGetDXTCNumDX10(ILenum DXTCFormat)
{
	switch (DXTCFormat)
	{
		case IL_DXT1:
			return D3DFMT_DXT1;
		case IL_DXT3:
			return D3DFMT_DXT3;
		case IL_DXT5:
			return D3DFMT_DXT5;
	}

	return D3DFMT_UNKNOWN;
}


//ILenum D3DGetDXTCFormat(D3DFORMAT DXTCNum)
//{
//	switch (DXTCNum)
//	{
//		case D3DFMT_DXT1:
//			return IL_DXT1;
//		case D3DFMT_DXT3:
//			return IL_DXT3;
//		case D3DFMT_DXT5:
//			return IL_DXT5;
//	}
//
//	return D3DFMT_UNKNOWN;
//}


// Code from http://msdn.microsoft.com/en-us/library/bb205131(VS.85).aspx#Creating_Empty_Textures
ID3D10Texture2D* iD3D10MakeTexture(ID3D10Device *Device, void *Data, ILuint Width, ILuint Height, DXGI_FORMAT Format, ILuint Levels)
{
	ID3D10Texture2D *Texture = NULL;
	D3D10_TEXTURE2D_DESC Desc;
	D3D10_SUBRESOURCE_DATA InitialData;

	Levels;

	Desc.Width = Width;
	Desc.Height = Height;
	Desc.MipLevels = 1;  //@TODO: Change for mipmaps.
	Desc.ArraySize = 1;  //@TODO: Change for mipmaps.
	Desc.Format = Format;
	Desc.SampleDesc.Count = 1;
	Desc.Usage = D3D10_USAGE_DEFAULT;
	Desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
	Desc.CPUAccessFlags = 0;  // Only need to put the data in initially.

	InitialData.pSysMem = Data;
	InitialData.SysMemPitch = 0;
	InitialData.SysMemSlicePitch = 0;
	
	if (FAILED(ID3D10Device_CreateTexture2D(Device, &Desc, &InitialData, &Texture)))
		return NULL;

	return Texture;
}

ID3D10Texture2D* ILAPIENTRY ilutD3D10Texture(ID3D10Device *Device)
{
	ID3D10Texture2D *Texture;
	DXGI_FORMAT Format;
	ILimage	*Image;

	Image = ilutCurImage = ilGetCurImage();
	if (ilutCurImage == NULL) {
		ilSetError(ILUT_ILLEGAL_OPERATION);
		return NULL;
	}

	if (!FormatsDX10Checked)
		CheckFormatsDX10(Device);

	Image = MakeD3D10Compliant(Device, &Format);
	if (Image == NULL) {
		if (Image != ilutCurImage)
			ilCloseImage(Image);
		return NULL;
	}

	Texture = iD3D10MakeTexture(Device, Image->Data, Image->Width, Image->Height, Format, 1);  //@TODO: The 1 should be ilutGetInteger(ILUT_D3D_MIPLEVELS).
	if (!Texture)
		return NULL;
	//iD3D10CreateMipmaps(Texture, Image);

//success:

	if (Image != ilutCurImage)
		ilCloseImage(Image);

	return Texture;
}


ILimage *MakeD3D10Compliant(ID3D10Device *Device, DXGI_FORMAT *DestFormat)
{
	ILimage	*Converted, *Scaled, *CurImage;
	ILuint nConversionType, ilutFormat;
	ILboolean bForceIntegerFormat = ilutGetBoolean(ILUT_FORCE_INTEGER_FORMAT);

	Device;
	ilutFormat = ilutCurImage->Format;
	nConversionType = ilutCurImage->Type;

	if (!ilutCurImage)
		return NULL;

	switch (ilutCurImage->Type)
	{
	case IL_UNSIGNED_BYTE:
	case IL_BYTE:
	case IL_SHORT:
	case IL_UNSIGNED_SHORT:
	case IL_INT:
	case IL_UNSIGNED_INT:
		*DestFormat     = DXGI_FORMAT_R8G8B8A8_UINT;
		nConversionType = IL_UNSIGNED_BYTE;
		ilutFormat      = IL_RGBA;
		break;
	case IL_FLOAT:
	case IL_DOUBLE:
	case IL_HALF:
		if (bForceIntegerFormat || (!FormatsDX10supported[6]))
		{
			*DestFormat     = DXGI_FORMAT_R8G8B8A8_UINT;
			nConversionType = IL_UNSIGNED_BYTE;
			ilutFormat      = IL_RGBA;
		}
		else
		{
			*DestFormat     = DXGI_FORMAT_R32G32B32A32_FLOAT;
			nConversionType = IL_HALF;
			ilutFormat      = IL_RGBA;
		}
		break;
	}

	// Images must be in BGRA format.
	if (((ilutCurImage->Format != ilutFormat))
		|| (ilutCurImage->Type != nConversionType)) 
	{
		Converted = iConvertImage(ilutCurImage, ilutFormat, nConversionType);
		if (Converted == NULL)
			return NULL;
	}
	else 
	{
		Converted = ilutCurImage;
	}

	// Images must have their origin in the upper left.
	if (Converted->Origin != IL_ORIGIN_UPPER_LEFT) 
	{
		CurImage = ilutCurImage;
		ilSetCurImage(Converted);
		iluFlipImage();
		ilSetCurImage(CurImage);
	}

	// Images must have powers-of-2 dimensions.
	if (ilNextPower2(ilutCurImage->Width) != ilutCurImage->Width ||
		ilNextPower2(ilutCurImage->Height) != ilutCurImage->Height ||
		ilNextPower2(ilutCurImage->Depth) != ilutCurImage->Depth) {
			Scaled = iluScale_(Converted, ilNextPower2(ilutCurImage->Width),
						ilNextPower2(ilutCurImage->Height), 1);  //@TODO: 1 should be ilNextPower2(ilutCurImage->Depth)
			if (Converted != ilutCurImage) {
				ilCloseImage(Converted);
			}
			if (Scaled == NULL) {
				return NULL;
			}
			Converted = Scaled;
	}

	return Converted;
}


#endif//ILUT_USE_DIRECTX10