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 23namespace D3D8 24{ 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 69 Direct3DVertexBuffer8::~Direct3DVertexBuffer8() 70 { 71 vertexBuffer->destruct(); 72 } 73 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 93 unsigned long Direct3DVertexBuffer8::AddRef() 94 { 95 TRACE(""); 96 97 return Direct3DResource8::AddRef(); 98 } 99 100 unsigned long Direct3DVertexBuffer8::Release() 101 { 102 TRACE(""); 103 104 return Direct3DResource8::Release(); 105 } 106 107 long Direct3DVertexBuffer8::FreePrivateData(const GUID &guid) 108 { 109 TRACE(""); 110 111 return Direct3DResource8::FreePrivateData(guid); 112 } 113 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 121 void Direct3DVertexBuffer8::PreLoad() 122 { 123 TRACE(""); 124 125 Direct3DResource8::PreLoad(); 126 } 127 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 135 long Direct3DVertexBuffer8::GetDevice(IDirect3DDevice8 **device) 136 { 137 TRACE(""); 138 139 return Direct3DResource8::GetDevice(device); 140 } 141 142 unsigned long Direct3DVertexBuffer8::SetPriority(unsigned long newPriority) 143 { 144 TRACE(""); 145 146 return Direct3DResource8::SetPriority(newPriority); 147 } 148 149 unsigned long Direct3DVertexBuffer8::GetPriority() 150 { 151 TRACE(""); 152 153 return Direct3DResource8::GetPriority(); 154 } 155 156 D3DRESOURCETYPE Direct3DVertexBuffer8::GetType() 157 { 158 TRACE(""); 159 160 return Direct3DResource8::GetType(); 161 } 162 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 186 long Direct3DVertexBuffer8::Unlock() 187 { 188 TRACE(""); 189 190 return D3D_OK; 191 } 192 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 212 int Direct3DVertexBuffer8::getLength() const 213 { 214 return length; 215 } 216 217 sw::Resource *Direct3DVertexBuffer8::getResource() const 218 { 219 return vertexBuffer; 220 } 221} 222