Nicolas Capens | 17b29fd | 2016-09-15 09:32:16 -0400 | [diff] [blame] | 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 | { |
| 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 | } |