Home | History | Annotate | Download | only in D3D8
      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 }
    222