1// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "Direct3DTexture8.hpp"
16
17#include "Direct3DSurface8.hpp"
18#include "Resource.hpp"
19#include "Debug.hpp"
20
21#include <assert.h>
22
23namespace D3D8
24{
25	Direct3DTexture8::Direct3DTexture8(Direct3DDevice8 *device, unsigned int width, unsigned int height, unsigned int levels, unsigned long usage, D3DFORMAT format, D3DPOOL pool) : Direct3DBaseTexture8(device, D3DRTYPE_TEXTURE, levels, usage), width(width), height(height), format(format), pool(pool)
26	{
27		if(levels == 0)
28		{
29			this->levels = sw::log2(sw::max((int)width, (int)height, 1)) + 1;
30		}
31
32		for(unsigned int level = 0; level < sw::MIPMAP_LEVELS; level++)
33		{
34			if(level < this->levels)
35			{
36				surfaceLevel[level] = new Direct3DSurface8(device, this, width, height, format, pool, D3DMULTISAMPLE_NONE, true, usage);
37				surfaceLevel[level]->bind();
38			}
39			else
40			{
41				surfaceLevel[level] = 0;
42			}
43
44			width = sw::max(1, (int)width / 2);
45			height = sw::max(1, (int)height / 2);
46		}
47	}
48
49	Direct3DTexture8::~Direct3DTexture8()
50	{
51		for(int level = 0; level < sw::MIPMAP_LEVELS; level++)
52		{
53			if(surfaceLevel[level])
54			{
55				surfaceLevel[level]->unbind();
56				surfaceLevel[level] = 0;
57			}
58		}
59	}
60
61	long Direct3DTexture8::QueryInterface(const IID &iid, void **object)
62	{
63		TRACE("");
64
65		if(iid == IID_IDirect3DTexture8 ||
66		   iid == IID_IDirect3DBaseTexture8 ||
67		   iid == IID_IDirect3DResource8 ||
68		   iid == IID_IUnknown)
69		{
70			AddRef();
71			*object = this;
72
73			return S_OK;
74		}
75
76		*object = 0;
77
78		return NOINTERFACE(iid);
79	}
80
81	unsigned long Direct3DTexture8::AddRef()
82	{
83		TRACE("");
84
85		return Direct3DBaseTexture8::AddRef();
86	}
87
88	unsigned long Direct3DTexture8::Release()
89	{
90		TRACE("");
91
92		return Direct3DBaseTexture8::Release();
93	}
94
95	long Direct3DTexture8::FreePrivateData(const GUID &guid)
96	{
97		TRACE("");
98
99		return Direct3DBaseTexture8::FreePrivateData(guid);
100	}
101
102	long Direct3DTexture8::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
103	{
104		TRACE("");
105
106		return Direct3DBaseTexture8::GetPrivateData(guid, data, size);
107	}
108
109	void Direct3DTexture8::PreLoad()
110	{
111		TRACE("");
112
113		Direct3DBaseTexture8::PreLoad();
114	}
115
116	long Direct3DTexture8::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
117	{
118		TRACE("");
119
120		return Direct3DBaseTexture8::SetPrivateData(guid, data, size, flags);
121	}
122
123	long Direct3DTexture8::GetDevice(IDirect3DDevice8 **device)
124	{
125		TRACE("");
126
127		return Direct3DBaseTexture8::GetDevice(device);
128	}
129
130	unsigned long Direct3DTexture8::SetPriority(unsigned long newPriority)
131	{
132		TRACE("");
133
134		return Direct3DBaseTexture8::SetPriority(newPriority);
135	}
136
137	unsigned long Direct3DTexture8::GetPriority()
138	{
139		TRACE("");
140
141		return Direct3DBaseTexture8::GetPriority();
142	}
143
144	D3DRESOURCETYPE Direct3DTexture8::GetType()
145	{
146		TRACE("");
147
148		return Direct3DBaseTexture8::GetType();
149	}
150
151	unsigned long Direct3DTexture8::GetLevelCount()
152	{
153		TRACE("");
154
155		return Direct3DBaseTexture8::GetLevelCount();
156	}
157
158	unsigned long Direct3DTexture8::GetLOD()
159	{
160		TRACE("");
161
162		return Direct3DBaseTexture8::GetLOD();
163	}
164
165	unsigned long Direct3DTexture8::SetLOD(unsigned long newLOD)
166	{
167		TRACE("");
168
169		return Direct3DBaseTexture8::SetLOD(newLOD);
170	}
171
172	long Direct3DTexture8::GetLevelDesc(unsigned int level, D3DSURFACE_DESC *description)
173	{
174		TRACE("");
175
176		if(level >= GetLevelCount() || !surfaceLevel[level])
177		{
178			return INVALIDCALL();
179		}
180
181		return surfaceLevel[level]->GetDesc(description);
182	}
183
184	long Direct3DTexture8::LockRect(unsigned int level, D3DLOCKED_RECT *lockedRect, const RECT *rect, unsigned long flags)
185	{
186		TRACE("");
187
188		if(!lockedRect || level >= GetLevelCount() || !surfaceLevel[level])
189		{
190			return INVALIDCALL();
191		}
192
193		return surfaceLevel[level]->LockRect(lockedRect, rect, flags);
194	}
195
196	long Direct3DTexture8::GetSurfaceLevel(unsigned int level, IDirect3DSurface8 **surface)
197	{
198		TRACE("");
199
200		*surface = 0;   // FIXME: Verify
201
202		if(level >= GetLevelCount() || !surfaceLevel[level])
203		{
204			return INVALIDCALL();
205		}
206
207		surfaceLevel[level]->AddRef();
208		*surface = surfaceLevel[level];
209
210		return D3D_OK;
211	}
212
213	long Direct3DTexture8::UnlockRect(unsigned int level)
214	{
215		TRACE("");
216
217		if(level >= GetLevelCount() || !surfaceLevel[level])
218		{
219			return INVALIDCALL();
220		}
221
222		return surfaceLevel[level]->UnlockRect();
223	}
224
225	long Direct3DTexture8::AddDirtyRect(const RECT *dirtyRect)
226	{
227		TRACE("");
228
229	//	UNIMPLEMENTED();
230
231		return D3D_OK;
232	}
233
234	Direct3DSurface8 *Direct3DTexture8::getInternalSurfaceLevel(unsigned int level)
235	{
236		return surfaceLevel[level];
237	}
238}
239