1 // Copyright (C) 2003 Dolphin Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official SVN repository and contact information can be found at
16 // http://code.google.com/p/dolphin-emu/
19 #include "D3DTexture.h"
24 LPDIRECT3DTEXTURE9
CreateTexture2D(const u8
* buffer
, const int width
, const int height
, const int pitch
, D3DFORMAT fmt
, bool swap_r_b
, int levels
)
26 u32
* pBuffer
= (u32
*)buffer
;
27 LPDIRECT3DTEXTURE9 pTexture
;
29 // crazy bitmagic, sorry :)
30 bool isPow2
= !((width
&(width
-1)) || (height
&(height
-1)));
33 if (fmt
== D3DFMT_A8P8
) {
39 // TODO(ector): Allow mipmaps for non-pow textures on newer cards?
40 // TODO(ector): Use the game-specified mipmaps?
42 hr
= dev
->CreateTexture(width
, height
, levels
, 0, fmt
, D3DPOOL_MANAGED
, &pTexture
, NULL
);
44 hr
= dev
->CreateTexture(width
, height
, 0, D3DUSAGE_AUTOGENMIPMAP
, fmt
, D3DPOOL_MANAGED
, &pTexture
, NULL
);
50 pTexture
->LockRect(level
, &Lock
, NULL
, 0);
57 const u8
*pIn
= buffer
;
58 for (int y
= 0; y
< height
; y
++)
60 u8
* pBits
= ((u8
*)Lock
.pBits
+ (y
* Lock
.Pitch
));
61 memcpy(pBits
, pIn
, width
);
68 const u16
*pIn
= (u16
*)buffer
;
69 for (int y
= 0; y
< height
; y
++)
71 u16
* pBits
= (u16
*)((u8
*)Lock
.pBits
+ (y
* Lock
.Pitch
));
72 memcpy(pBits
, pIn
, width
* 2);
80 const u8
*pIn
= buffer
;
81 // TODO(XK): Find a better way that does not involve either unpacking
82 // or downsampling (i.e. A4L4)
83 for (int y
= 0; y
< height
; y
++)
85 u8
* pBits
= ((u8
*)Lock
.pBits
+ (y
* Lock
.Pitch
));
86 for(int i
= 0; i
< width
* 2; i
+= 2) {
87 pBits
[i
] = pIn
[i
/ 2];
88 pBits
[i
+ 1] = pIn
[i
/ 2];
93 const u16
*pIn
= (u16
*)buffer
;
95 for (int y
= 0; y
< height
; y
++)
97 u16
* pBits
= (u16
*)((u8
*)Lock
.pBits
+ (y
* Lock
.Pitch
));
98 memcpy(pBits
, pIn
, width
* 2);
104 case D3DFMT_A8R8G8B8
:
106 if(pitch
* 4 == Lock
.Pitch
&& !swap_r_b
)
108 memcpy(Lock
.pBits
,buffer
,Lock
.Pitch
*height
);
114 for (int y
= 0; y
< height
; y
++)
116 u32
*pBits
= (u32
*)((u8
*)Lock
.pBits
+ (y
* Lock
.Pitch
));
117 memcpy(pBits
, pIn
, width
* 4);
121 for (int y
= 0; y
< height
; y
++)
123 u8
*pIn8
= (u8
*)pIn
;
124 u8
*pBits
= (u8
*)((u8
*)Lock
.pBits
+ (y
* Lock
.Pitch
));
125 for (int x
= 0; x
< width
* 4; x
+= 4) {
126 pBits
[x
+ 0] = pIn8
[x
+ 2];
127 pBits
[x
+ 1] = pIn8
[x
+ 1];
128 pBits
[x
+ 2] = pIn8
[x
+ 0];
129 pBits
[x
+ 3] = pIn8
[x
+ 3];
138 memcpy(Lock
.pBits
,buffer
,((width
+3)/4)*((height
+3)/4)*8);
141 PanicAlert("D3D: Invalid texture format %i", fmt
);
143 pTexture
->UnlockRect(level
);
147 LPDIRECT3DTEXTURE9
CreateOnlyTexture2D(const int width
, const int height
, D3DFORMAT fmt
)
149 LPDIRECT3DTEXTURE9 pTexture
;
150 // crazy bitmagic, sorry :)
151 bool isPow2
= !((width
&(width
-1)) || (height
&(height
-1)));
152 bool bExpand
= false;
154 // TODO(ector): Allow mipmaps for non-pow textures on newer cards?
155 // TODO(ector): Use the game-specified mipmaps?
157 hr
= dev
->CreateTexture(width
, height
, 1, 0, fmt
, D3DPOOL_MANAGED
, &pTexture
, NULL
);
159 hr
= dev
->CreateTexture(width
, height
, 0, D3DUSAGE_AUTOGENMIPMAP
, fmt
, D3DPOOL_MANAGED
, &pTexture
, NULL
);
166 void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture
, const u8
* buffer
, const int width
, const int height
, const int pitch
, D3DFORMAT fmt
, bool swap_r_b
, int level
)
168 u32
* pBuffer
= (u32
*)buffer
;
170 pTexture
->LockRect(level
, &Lock
, NULL
, 0);
173 bool bExpand
= false;
175 if (fmt
== D3DFMT_A8P8
) {
181 case D3DFMT_A8R8G8B8
:
182 if(pitch
* 4 == Lock
.Pitch
&& !swap_r_b
)
184 memcpy(Lock
.pBits
, pBuffer
, Lock
.Pitch
*height
);
188 for (int y
= 0; y
< height
; y
++)
190 u32
*pBits
= (u32
*)((u8
*)Lock
.pBits
+ (y
* Lock
.Pitch
));
191 memcpy(pBits
, pIn
, width
* 4);
197 for (int y
= 0; y
< height
; y
++)
199 u8
*pIn8
= (u8
*)pIn
;
200 u8
*pBits
= (u8
*)((u8
*)Lock
.pBits
+ (y
* Lock
.Pitch
));
201 for (int x
= 0; x
< width
* 4; x
+= 4)
203 pBits
[x
+ 0] = pIn8
[x
+ 2];
204 pBits
[x
+ 1] = pIn8
[x
+ 1];
205 pBits
[x
+ 2] = pIn8
[x
+ 0];
206 pBits
[x
+ 3] = pIn8
[x
+ 3];
216 const u8
*pIn
= buffer
;
217 for (int y
= 0; y
< height
; y
++)
219 u8
* pBits
= ((u8
*)Lock
.pBits
+ (y
* Lock
.Pitch
));
220 memcpy(pBits
, pIn
, width
);
227 const u16
*pIn
= (u16
*)buffer
;
228 for (int y
= 0; y
< height
; y
++)
230 u16
* pBits
= (u16
*)((u8
*)Lock
.pBits
+ (y
* Lock
.Pitch
));
231 memcpy(pBits
, pIn
, width
* 2);
239 const u8
*pIn
= buffer
;
240 // TODO(XK): Find a better way that does not involve either unpacking
241 // or downsampling (i.e. A4L4)
242 for (int y
= 0; y
< height
; y
++)
244 u8
* pBits
= ((u8
*)Lock
.pBits
+ (y
* Lock
.Pitch
));
245 for(int i
= 0; i
< width
* 2; i
+= 2) {
246 pBits
[i
] = pIn
[i
/ 2];
247 pBits
[i
+ 1] = pIn
[i
/ 2];
252 const u16
*pIn
= (u16
*)buffer
;
254 for (int y
= 0; y
< height
; y
++)
256 u16
* pBits
= (u16
*)((u8
*)Lock
.pBits
+ (y
* Lock
.Pitch
));
257 memcpy(pBits
, pIn
, width
* 2);
264 memcpy(Lock
.pBits
,buffer
,((width
+3)/4)*((height
+3)/4)*8);
267 pTexture
->UnlockRect(level
);