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