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 "Direct3DVolume9.hpp"
16 
17 #include "Direct3DDevice9.hpp"
18 #include "Direct3DResource9.hpp"
19 #include "Direct3DVolumeTexture9.hpp"
20 #include "Direct3DSurface9.hpp"
21 #include "Resource.hpp"
22 #include "Debug.hpp"
23 
24 #include <assert.h>
25 
26 namespace D3D9
27 {
isLockable(D3DPOOL pool,unsigned long usage)28 	bool isLockable(D3DPOOL pool, unsigned long usage)
29 	{
30 		return (pool != D3DPOOL_DEFAULT) || (usage & D3DUSAGE_DYNAMIC);
31 	}
32 
Direct3DVolume9(Direct3DDevice9 * device,Direct3DVolumeTexture9 * container,int width,int height,int depth,D3DFORMAT format,D3DPOOL pool,unsigned long usage)33 	Direct3DVolume9::Direct3DVolume9(Direct3DDevice9 *device, Direct3DVolumeTexture9 *container, int width, int height, int depth, D3DFORMAT format, D3DPOOL pool, unsigned long usage) : device(device), Surface(container->getResource(), width, height, depth, translateFormat(format), isLockable(pool, usage), false), container(container), width(width), height(height), depth(depth), format(format), pool(pool), lockable(isLockable(pool, usage)), usage(usage)
34 	{
35 		resource = new Direct3DResource9(device, D3DRTYPE_VOLUME, pool, memoryUsage(width, height, depth, format));
36 		resource->bind();
37 	}
38 
~Direct3DVolume9()39 	Direct3DVolume9::~Direct3DVolume9()
40 	{
41 		resource->unbind();
42 	}
43 
QueryInterface(const IID & iid,void ** object)44 	long __stdcall Direct3DVolume9::QueryInterface(const IID &iid, void **object)
45 	{
46 		CriticalSection cs(device);
47 
48 		TRACE("");
49 
50 		if(iid == IID_IDirect3DVolume9 ||
51 		   iid == IID_IUnknown)
52 		{
53 			AddRef();
54 			*object = this;
55 
56 			return S_OK;
57 		}
58 
59 		*object = 0;
60 
61 		return NOINTERFACE(iid);
62 	}
63 
AddRef()64 	unsigned long __stdcall Direct3DVolume9::AddRef()
65 	{
66 		TRACE("");
67 
68 		return container->AddRef();
69 	}
70 
Release()71 	unsigned long __stdcall Direct3DVolume9::Release()
72 	{
73 		TRACE("");
74 
75 		return container->Release();
76 	}
77 
FreePrivateData(const GUID & guid)78 	long Direct3DVolume9::FreePrivateData(const GUID &guid)
79 	{
80 		CriticalSection cs(device);
81 
82 		TRACE("");
83 
84 		return resource->FreePrivateData(guid);
85 	}
86 
GetContainer(const IID & iid,void ** container)87 	long Direct3DVolume9::GetContainer(const IID &iid, void **container)
88 	{
89 		CriticalSection cs(device);
90 
91 		TRACE("");
92 
93 		if(!container)
94 		{
95 			return INVALIDCALL();
96 		}
97 
98 		long result = this->container->QueryInterface(iid, container);
99 
100 		if(result == S_OK)
101 		{
102 			return D3D_OK;
103 		}
104 
105 		return INVALIDCALL();
106 	}
107 
GetDesc(D3DVOLUME_DESC * description)108 	long Direct3DVolume9::GetDesc(D3DVOLUME_DESC *description)
109 	{
110 		CriticalSection cs(device);
111 
112 		TRACE("");
113 
114 		if(!description)
115 		{
116 			return INVALIDCALL();
117 		}
118 
119 		description->Format = format;
120 		description->Type = D3DRTYPE_VOLUME;
121 		description->Usage = usage;
122 		description->Pool = pool;
123 		description->Width = width;
124 		description->Height = height;
125 		description->Depth = depth;
126 
127 		return D3D_OK;
128 	}
129 
GetDevice(IDirect3DDevice9 ** device)130 	long Direct3DVolume9::GetDevice(IDirect3DDevice9 **device)
131 	{
132 		CriticalSection cs(this->device);
133 
134 		TRACE("");
135 
136 		return resource->GetDevice(device);
137 	}
138 
GetPrivateData(const GUID & guid,void * data,unsigned long * size)139 	long Direct3DVolume9::GetPrivateData(const GUID &guid, void *data, unsigned long *size)
140 	{
141 		CriticalSection cs(device);
142 
143 		TRACE("");
144 
145 		return resource->GetPrivateData(guid, data, size);
146 	}
147 
LockBox(D3DLOCKED_BOX * lockedVolume,const D3DBOX * box,unsigned long flags)148 	long Direct3DVolume9::LockBox(D3DLOCKED_BOX *lockedVolume, const D3DBOX *box, unsigned long flags)
149 	{
150 		CriticalSection cs(device);
151 
152 		TRACE("");
153 
154 		if(!lockedVolume)
155 		{
156 			return INVALIDCALL();
157 		}
158 
159 		lockedVolume->RowPitch = 0;
160 		lockedVolume->SlicePitch = 0;
161 		lockedVolume->pBits = 0;
162 
163 		if(!lockable)
164 		{
165 			return INVALIDCALL();
166 		}
167 
168 		lockedVolume->RowPitch = getExternalPitchB();
169 		lockedVolume->SlicePitch = getExternalSliceB();
170 
171 		sw::Lock lock = sw::LOCK_READWRITE;
172 
173 		if(flags & D3DLOCK_DISCARD)
174 		{
175 			lock = sw::LOCK_DISCARD;
176 		}
177 
178 		if(flags & D3DLOCK_READONLY)
179 		{
180 			lock = sw::LOCK_READONLY;
181 		}
182 
183 		if(box)
184 		{
185 			lockedVolume->pBits = lockExternal(box->Left, box->Top, box->Front, lock, sw::PUBLIC);
186 		}
187 		else
188 		{
189 			lockedVolume->pBits = lockExternal(0, 0, 0, lock, sw::PUBLIC);
190 		}
191 
192 		return D3D_OK;
193 	}
194 
SetPrivateData(const GUID & guid,const void * data,unsigned long size,unsigned long flags)195 	long Direct3DVolume9::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags)
196 	{
197 		CriticalSection cs(device);
198 
199 		TRACE("");
200 
201 		return resource->SetPrivateData(guid, data, size, flags);
202 	}
203 
UnlockBox()204 	long Direct3DVolume9::UnlockBox()
205 	{
206 		CriticalSection cs(device);
207 
208 		TRACE("");
209 
210 		unlockExternal();
211 
212 		return D3D_OK;
213 	}
214 
translateFormat(D3DFORMAT format)215 	sw::Format Direct3DVolume9::translateFormat(D3DFORMAT format)
216 	{
217 		return Direct3DSurface9::translateFormat(format);
218 	}
219 
memoryUsage(int width,int height,int depth,D3DFORMAT format)220 	unsigned int Direct3DVolume9::memoryUsage(int width, int height, int depth, D3DFORMAT format)
221 	{
222 		return Surface::size(width, height, depth, translateFormat(format));
223 	}
224 }
225