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 "Direct3DIndexBuffer9.hpp"
16 
17 #include "Direct3DDevice9.hpp"
18 #include "Resource.hpp"
19 #include "Debug.hpp"
20 
21 #include <assert.h>
22 
23 namespace D3D9
24 {
Direct3DIndexBuffer9(Direct3DDevice9 * device,unsigned int length,unsigned long usage,D3DFORMAT format,D3DPOOL pool)25 	Direct3DIndexBuffer9::Direct3DIndexBuffer9(Direct3DDevice9 *device, unsigned int length, unsigned long usage, D3DFORMAT format, D3DPOOL pool) : Direct3DResource9(device, D3DRTYPE_INDEXBUFFER, pool, length), length(length), usage(usage), format(format)
26 	{
27 		indexBuffer = new sw::Resource(length + 16);
28 		lockCount = 0;
29 	}
30 
~Direct3DIndexBuffer9()31 	Direct3DIndexBuffer9::~Direct3DIndexBuffer9()
32 	{
33 		indexBuffer->destruct();
34 	}
35 
QueryInterface(const IID & iid,void ** object)36 	long Direct3DIndexBuffer9::QueryInterface(const IID &iid, void **object)
37 	{
38 		CriticalSection cs(device);
39 
40 		TRACE("");
41 
42 		if(iid == IID_IDirect3DIndexBuffer9 ||
43 		   iid == IID_IDirect3DResource9 ||
44 		   iid == IID_IUnknown)
45 		{
46 			AddRef();
47 			*object = this;
48 
49 			return S_OK;
50 		}
51 
52 		*object = 0;
53 
54 		return NOINTERFACE(iid);
55 	}
56 
AddRef()57 	unsigned long Direct3DIndexBuffer9::AddRef()
58 	{
59 		TRACE("");
60 
61 		return Direct3DResource9::AddRef();
62 	}
63 
Release()64 	unsigned long Direct3DIndexBuffer9::Release()
65 	{
66 		TRACE("");
67 
68 		return Direct3DResource9::Release();
69 	}
70 
FreePrivateData(const GUID & guid)71 	long Direct3DIndexBuffer9::FreePrivateData(const GUID &guid)
72 	{
73 		CriticalSection cs(device);
74 
75 		TRACE("");
76 
77 		return Direct3DResource9::FreePrivateData(guid);
78 	}
79 
GetPrivateData(const GUID & guid,void * data,unsigned long * size)80 	long Direct3DIndexBuffer9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
81 	{
82 		CriticalSection cs(device);
83 
84 		TRACE("");
85 
86 		return Direct3DResource9::GetPrivateData(guid, data, size);
87 	}
88 
PreLoad()89 	void Direct3DIndexBuffer9::PreLoad()
90 	{
91 		CriticalSection cs(device);
92 
93 		TRACE("");
94 
95 		Direct3DResource9::PreLoad();
96 	}
97 
SetPrivateData(const GUID & guid,const void * data,unsigned long size,unsigned long flags)98 	long Direct3DIndexBuffer9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
99 	{
100 		CriticalSection cs(device);
101 
102 		TRACE("");
103 
104 		return Direct3DResource9::SetPrivateData(guid, data, size, flags);
105 	}
106 
GetDevice(IDirect3DDevice9 ** device)107 	long Direct3DIndexBuffer9::GetDevice(IDirect3DDevice9 **device)
108 	{
109 		CriticalSection cs(this->device);
110 
111 		TRACE("");
112 
113 		return Direct3DResource9::GetDevice(device);
114 	}
115 
SetPriority(unsigned long newPriority)116 	unsigned long Direct3DIndexBuffer9::SetPriority(unsigned long newPriority)
117 	{
118 		CriticalSection cs(device);
119 
120 		TRACE("");
121 
122 		return Direct3DResource9::SetPriority(newPriority);
123 	}
124 
GetPriority()125 	unsigned long Direct3DIndexBuffer9::GetPriority()
126 	{
127 		CriticalSection cs(device);
128 
129 		TRACE("");
130 
131 		return Direct3DResource9::GetPriority();
132 	}
133 
GetType()134 	D3DRESOURCETYPE Direct3DIndexBuffer9::GetType()
135 	{
136 		CriticalSection cs(device);
137 
138 		TRACE("");
139 
140 		return Direct3DResource9::GetType();
141 	}
142 
GetDesc(D3DINDEXBUFFER_DESC * description)143 	long Direct3DIndexBuffer9::GetDesc(D3DINDEXBUFFER_DESC *description)
144 	{
145 		CriticalSection cs(device);
146 
147 		TRACE("");
148 
149 		if(!description)
150 		{
151 			return INVALIDCALL();
152 		}
153 
154 		description->Format = format;
155 		description->Pool = pool;
156 		description->Size = length;
157 		description->Type = GetType();
158 		description->Usage = usage;
159 
160 		return 0;
161 	}
162 
Lock(unsigned int offset,unsigned int size,void ** data,unsigned long flags)163 	long Direct3DIndexBuffer9::Lock(unsigned int offset, unsigned int size, void **data, unsigned long flags)
164 	{
165 		CriticalSection cs(device);
166 
167 		TRACE("");
168 
169 		if(offset == 0 && size == 0)   // Lock whole buffer
170 		{
171 			size = length;
172 		}
173 
174 		if(!data || offset > length || offset + size > length)
175 		{
176 			return INVALIDCALL();
177 		}
178 
179 		void *buffer;
180 
181 		if(flags & D3DLOCK_DISCARD/* && usage & D3DUSAGE_DYNAMIC*/)
182 		{
183 			indexBuffer->destruct();
184 			indexBuffer = new sw::Resource(length + 16);
185 
186 			buffer = (void*)indexBuffer->data();
187 		}
188 		else if(flags & D3DLOCK_NOOVERWRITE/* && usage & D3DUSAGE_DYNAMIC*/)
189 		{
190 			buffer = (void*)indexBuffer->data();
191 		}
192 		else
193 		{
194 			buffer = indexBuffer->lock(sw::PUBLIC);
195 			lockCount++;
196 		}
197 
198 		*data = (unsigned char*)buffer + offset;
199 
200 		return D3D_OK;
201 	}
202 
Unlock()203 	long Direct3DIndexBuffer9::Unlock()
204 	{
205 		CriticalSection cs(device);
206 
207 		TRACE("");
208 
209 		if(lockCount > 0)
210 		{
211 			indexBuffer->unlock();
212 			lockCount--;
213 		}
214 
215 		return D3D_OK;
216 	}
217 
getResource() const218 	sw::Resource *Direct3DIndexBuffer9::getResource() const
219 	{
220 		return indexBuffer;
221 	}
222 
is32Bit() const223 	bool Direct3DIndexBuffer9::is32Bit() const
224 	{
225 		switch(format)
226 		{
227 		case D3DFMT_INDEX16:
228 			return false;
229 		case D3DFMT_INDEX32:
230 			return true;
231 		default:
232 			ASSERT(false);
233 		}
234 
235 		return false;
236 	}
237 }
238