• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "Direct3DVertexBuffer9.hpp"
16 
17 #include "Direct3DDevice9.hpp"
18 #include "Resource.hpp"
19 #include "Debug.hpp"
20 
21 #include <assert.h>
22 
23 namespace D3D9
24 {
Direct3DVertexBuffer9(Direct3DDevice9 * device,unsigned int length,unsigned long usage,long FVF,D3DPOOL pool)25 	Direct3DVertexBuffer9::Direct3DVertexBuffer9(Direct3DDevice9 *device, unsigned int length, unsigned long usage, long FVF, D3DPOOL pool) : Direct3DResource9(device, D3DRTYPE_VERTEXBUFFER, pool, length), length(length), usage(usage), FVF(FVF)
26 	{
27 		if(FVF)
28 		{
29 			unsigned int stride = 0;
30 
31 			switch(FVF & D3DFVF_POSITION_MASK)
32 			{
33 			case D3DFVF_XYZ:	stride += 12;	break;
34 			case D3DFVF_XYZRHW:	stride += 16;	break;
35 			case D3DFVF_XYZB1:	stride += 16;	break;
36 			case D3DFVF_XYZB2:	stride += 20;	break;
37 			case D3DFVF_XYZB3:	stride += 24;	break;
38 			case D3DFVF_XYZB4:	stride += 28;	break;
39 			case D3DFVF_XYZB5:	stride += 32;	break;
40 			case D3DFVF_XYZW:   stride += 16;   break;
41 			}
42 
43 			if(FVF & D3DFVF_NORMAL)   stride += 12;
44 			if(FVF & D3DFVF_PSIZE)    stride += 4;
45 			if(FVF & D3DFVF_DIFFUSE)  stride += 4;
46 			if(FVF & D3DFVF_SPECULAR) stride += 4;
47 
48 			switch((FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT)
49 			{
50 			case 8: stride += 4 + 4 * ((1 + (FVF >> 30)) % 4);
51 			case 7: stride += 4 + 4 * ((1 + (FVF >> 28)) % 4);
52 			case 6: stride += 4 + 4 * ((1 + (FVF >> 26)) % 4);
53 			case 5: stride += 4 + 4 * ((1 + (FVF >> 24)) % 4);
54 			case 4: stride += 4 + 4 * ((1 + (FVF >> 22)) % 4);
55 			case 3: stride += 4 + 4 * ((1 + (FVF >> 20)) % 4);
56 			case 2: stride += 4 + 4 * ((1 + (FVF >> 18)) % 4);
57 			case 1: stride += 4 + 4 * ((1 + (FVF >> 16)) % 4);
58 			case 0: break;
59 			default:
60 				ASSERT(false);
61 			}
62 
63 			ASSERT(length >= stride);       // FIXME
64 		}
65 
66 		vertexBuffer = new sw::Resource(length + 192 + 1024);   // NOTE: Applications can 'overshoot' while writing vertices
67 		lockCount = 0;
68 	}
69 
~Direct3DVertexBuffer9()70 	Direct3DVertexBuffer9::~Direct3DVertexBuffer9()
71 	{
72 		vertexBuffer->destruct();
73 	}
74 
QueryInterface(const IID & iid,void ** object)75 	long Direct3DVertexBuffer9::QueryInterface(const IID &iid, void **object)
76 	{
77 		CriticalSection cs(device);
78 
79 		TRACE("");
80 
81 		if(iid == IID_IDirect3DVertexBuffer9 ||
82 		   iid == IID_IDirect3DResource9 ||
83 		   iid == IID_IUnknown)
84 		{
85 			AddRef();
86 			*object = this;
87 
88 			return S_OK;
89 		}
90 
91 		*object = 0;
92 
93 		return NOINTERFACE(iid);
94 	}
95 
AddRef()96 	unsigned long Direct3DVertexBuffer9::AddRef()
97 	{
98 		TRACE("");
99 
100 		return Direct3DResource9::AddRef();
101 	}
102 
Release()103 	unsigned long Direct3DVertexBuffer9::Release()
104 	{
105 		TRACE("");
106 
107 		return Direct3DResource9::Release();
108 	}
109 
FreePrivateData(const GUID & guid)110 	long Direct3DVertexBuffer9::FreePrivateData(const GUID &guid)
111 	{
112 		CriticalSection cs(device);
113 
114 		TRACE("");
115 
116 		return Direct3DResource9::FreePrivateData(guid);
117 	}
118 
GetPrivateData(const GUID & guid,void * data,unsigned long * size)119 	long Direct3DVertexBuffer9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
120 	{
121 		CriticalSection cs(device);
122 
123 		TRACE("");
124 
125 		return Direct3DResource9::GetPrivateData(guid, data, size);
126 	}
127 
PreLoad()128 	void Direct3DVertexBuffer9::PreLoad()
129 	{
130 		CriticalSection cs(device);
131 
132 		TRACE("");
133 
134 		Direct3DResource9::PreLoad();
135 	}
136 
SetPrivateData(const GUID & guid,const void * data,unsigned long size,unsigned long flags)137 	long Direct3DVertexBuffer9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
138 	{
139 		CriticalSection cs(device);
140 
141 		TRACE("");
142 
143 		return Direct3DResource9::SetPrivateData(guid, data, size, flags);
144 	}
145 
GetDevice(IDirect3DDevice9 ** device)146 	long Direct3DVertexBuffer9::GetDevice(IDirect3DDevice9 **device)
147 	{
148 		CriticalSection cs(this->device);
149 
150 		TRACE("");
151 
152 		return Direct3DResource9::GetDevice(device);
153 	}
154 
SetPriority(unsigned long newPriority)155 	unsigned long Direct3DVertexBuffer9::SetPriority(unsigned long newPriority)
156 	{
157 		CriticalSection cs(device);
158 
159 		TRACE("");
160 
161 		return Direct3DResource9::SetPriority(newPriority);
162 	}
163 
GetPriority()164 	unsigned long Direct3DVertexBuffer9::GetPriority()
165 	{
166 		CriticalSection cs(device);
167 
168 		TRACE("");
169 
170 		return Direct3DResource9::GetPriority();
171 	}
172 
GetType()173 	D3DRESOURCETYPE Direct3DVertexBuffer9::GetType()
174 	{
175 		CriticalSection cs(device);
176 
177 		TRACE("");
178 
179 		return Direct3DResource9::GetType();
180 	}
181 
Lock(unsigned int offset,unsigned int size,void ** data,unsigned long flags)182 	long Direct3DVertexBuffer9::Lock(unsigned int offset, unsigned int size, void **data, unsigned long flags)
183 	{
184 		CriticalSection cs(device);
185 
186 		TRACE("");
187 
188 		if(offset == 0 && size == 0)   // Lock whole buffer
189 		{
190 			size = length;
191 		}
192 
193 		if(!data || offset + size > length)
194 		{
195 			return INVALIDCALL();
196 		}
197 
198 		void *buffer;
199 
200 		if(flags & D3DLOCK_DISCARD/* && usage & D3DUSAGE_DYNAMIC*/)
201 		{
202 			vertexBuffer->destruct();
203 			vertexBuffer = new sw::Resource(length + 192 + 1024);   // NOTE: Applications can 'overshoot' while writing vertices
204 
205 			buffer = (void*)vertexBuffer->data();
206 		}
207 		else if(flags & D3DLOCK_NOOVERWRITE/* && usage & D3DUSAGE_DYNAMIC*/)
208 		{
209 			buffer = (void*)vertexBuffer->data();
210 		}
211 		else
212 		{
213 			buffer = vertexBuffer->lock(sw::PUBLIC);
214 			lockCount++;
215 		}
216 
217 		*data = (unsigned char*)buffer + offset;
218 
219 		return D3D_OK;
220 	}
221 
Unlock()222 	long Direct3DVertexBuffer9::Unlock()
223 	{
224 		CriticalSection cs(device);
225 
226 		TRACE("");
227 
228 		if(lockCount > 0)
229 		{
230 			vertexBuffer->unlock();
231 			lockCount--;
232 		}
233 
234 		return D3D_OK;
235 	}
236 
GetDesc(D3DVERTEXBUFFER_DESC * description)237 	long Direct3DVertexBuffer9::GetDesc(D3DVERTEXBUFFER_DESC *description)
238 	{
239 		CriticalSection cs(device);
240 
241 		TRACE("");
242 
243 		if(!description)
244 		{
245 			return INVALIDCALL();
246 		}
247 
248 		description->FVF = FVF;
249 		description->Format = D3DFMT_VERTEXDATA;
250 		description->Pool = pool;
251 		description->Size = length;
252 		description->Type = D3DRTYPE_VERTEXBUFFER;
253 		description->Usage = usage;
254 
255 		return D3D_OK;
256 	}
257 
getLength() const258 	int Direct3DVertexBuffer9::getLength() const
259 	{
260 		return length;
261 	}
262 
getResource() const263 	sw::Resource *Direct3DVertexBuffer9::getResource() const
264 	{
265 		return vertexBuffer;
266 	}
267 }
268