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 "Direct3DVertexBuffer8.hpp" 16 17 #include "Direct3DDevice8.hpp" 18 #include "Resource.hpp" 19 #include "Debug.hpp" 20 21 #include <assert.h> 22 23 namespace D3D8 24 { Direct3DVertexBuffer8(Direct3DDevice8 * device,unsigned int length,unsigned long usage,long FVF,D3DPOOL pool)25 Direct3DVertexBuffer8::Direct3DVertexBuffer8(Direct3DDevice8 *device, unsigned int length, unsigned long usage, long FVF, D3DPOOL pool) : Direct3DResource8(device, D3DRTYPE_VERTEXBUFFER, length), length(length), usage(usage), FVF(FVF), pool(pool) 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 } 41 42 if(FVF & D3DFVF_NORMAL) stride += 12; 43 if(FVF & D3DFVF_PSIZE) stride += 4; 44 if(FVF & D3DFVF_DIFFUSE) stride += 4; 45 if(FVF & D3DFVF_SPECULAR) stride += 4; 46 47 switch((FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) 48 { 49 case 8: stride += 4 + 4 * ((1 + (FVF >> 30)) % 4); 50 case 7: stride += 4 + 4 * ((1 + (FVF >> 28)) % 4); 51 case 6: stride += 4 + 4 * ((1 + (FVF >> 26)) % 4); 52 case 5: stride += 4 + 4 * ((1 + (FVF >> 24)) % 4); 53 case 4: stride += 4 + 4 * ((1 + (FVF >> 22)) % 4); 54 case 3: stride += 4 + 4 * ((1 + (FVF >> 20)) % 4); 55 case 2: stride += 4 + 4 * ((1 + (FVF >> 18)) % 4); 56 case 1: stride += 4 + 4 * ((1 + (FVF >> 16)) % 4); 57 case 0: break; 58 default: 59 ASSERT(false); 60 } 61 62 ASSERT(length >= stride); // FIXME 63 ASSERT(length % stride == 0); // D3D vertex size calculated incorrectly // FIXME 64 } 65 66 vertexBuffer = new sw::Resource(length + 192 + 1024); // NOTE: Applications can 'overshoot' while writing vertices 67 } 68 ~Direct3DVertexBuffer8()69 Direct3DVertexBuffer8::~Direct3DVertexBuffer8() 70 { 71 vertexBuffer->destruct(); 72 } 73 QueryInterface(const IID & iid,void ** object)74 long Direct3DVertexBuffer8::QueryInterface(const IID &iid, void **object) 75 { 76 TRACE(""); 77 78 if(iid == IID_IDirect3DVertexBuffer8 || 79 iid == IID_IDirect3DResource8 || 80 iid == IID_IUnknown) 81 { 82 AddRef(); 83 *object = this; 84 85 return S_OK; 86 } 87 88 *object = 0; 89 90 return NOINTERFACE(iid); 91 } 92 AddRef()93 unsigned long Direct3DVertexBuffer8::AddRef() 94 { 95 TRACE(""); 96 97 return Direct3DResource8::AddRef(); 98 } 99 Release()100 unsigned long Direct3DVertexBuffer8::Release() 101 { 102 TRACE(""); 103 104 return Direct3DResource8::Release(); 105 } 106 FreePrivateData(const GUID & guid)107 long Direct3DVertexBuffer8::FreePrivateData(const GUID &guid) 108 { 109 TRACE(""); 110 111 return Direct3DResource8::FreePrivateData(guid); 112 } 113 GetPrivateData(const GUID & guid,void * data,unsigned long * size)114 long Direct3DVertexBuffer8::GetPrivateData(const GUID &guid, void *data, unsigned long *size) 115 { 116 TRACE(""); 117 118 return Direct3DResource8::GetPrivateData(guid, data, size); 119 } 120 PreLoad()121 void Direct3DVertexBuffer8::PreLoad() 122 { 123 TRACE(""); 124 125 Direct3DResource8::PreLoad(); 126 } 127 SetPrivateData(const GUID & guid,const void * data,unsigned long size,unsigned long flags)128 long Direct3DVertexBuffer8::SetPrivateData(const GUID &guid, const void *data, unsigned long size, unsigned long flags) 129 { 130 TRACE(""); 131 132 return Direct3DResource8::SetPrivateData(guid, data, size, flags); 133 } 134 GetDevice(IDirect3DDevice8 ** device)135 long Direct3DVertexBuffer8::GetDevice(IDirect3DDevice8 **device) 136 { 137 TRACE(""); 138 139 return Direct3DResource8::GetDevice(device); 140 } 141 SetPriority(unsigned long newPriority)142 unsigned long Direct3DVertexBuffer8::SetPriority(unsigned long newPriority) 143 { 144 TRACE(""); 145 146 return Direct3DResource8::SetPriority(newPriority); 147 } 148 GetPriority()149 unsigned long Direct3DVertexBuffer8::GetPriority() 150 { 151 TRACE(""); 152 153 return Direct3DResource8::GetPriority(); 154 } 155 GetType()156 D3DRESOURCETYPE Direct3DVertexBuffer8::GetType() 157 { 158 TRACE(""); 159 160 return Direct3DResource8::GetType(); 161 } 162 Lock(unsigned int offset,unsigned int size,unsigned char ** data,unsigned long flags)163 long Direct3DVertexBuffer8::Lock(unsigned int offset, unsigned int size, unsigned char **data, unsigned long flags) 164 { 165 TRACE(""); 166 167 if(offset == 0 && size == 0) // Lock whole buffer 168 { 169 size = length; 170 } 171 172 if(!data || offset + size > length) 173 { 174 return INVALIDCALL(); 175 } 176 177 lockOffset = offset; 178 lockSize = size; 179 180 *data = (unsigned char*)vertexBuffer->lock(sw::PUBLIC) + offset; 181 vertexBuffer->unlock(); 182 183 return D3D_OK; 184 } 185 Unlock()186 long Direct3DVertexBuffer8::Unlock() 187 { 188 TRACE(""); 189 190 return D3D_OK; 191 } 192 GetDesc(D3DVERTEXBUFFER_DESC * description)193 long Direct3DVertexBuffer8::GetDesc(D3DVERTEXBUFFER_DESC *description) 194 { 195 TRACE(""); 196 197 if(!description) 198 { 199 return INVALIDCALL(); 200 } 201 202 description->FVF = FVF; 203 description->Format = D3DFMT_VERTEXDATA; 204 description->Pool = pool; 205 description->Size = length; 206 description->Type = D3DRTYPE_VERTEXBUFFER; 207 description->Usage = usage; 208 209 return D3D_OK; 210 } 211 getLength() const212 int Direct3DVertexBuffer8::getLength() const 213 { 214 return length; 215 } 216 getResource() const217 sw::Resource *Direct3DVertexBuffer8::getResource() const 218 { 219 return vertexBuffer; 220 } 221 } 222