7#include "ps2s/cpu_matrix.h"
9#include "ps2s/packet.h"
11#include "ps2gl/drawcontext.h"
12#include "ps2gl/glcontext.h"
13#include "ps2gl/immgmanager.h"
14#include "ps2gl/lighting.h"
15#include "ps2gl/linear_renderer.h"
16#include "ps2gl/material.h"
17#include "ps2gl/matrix.h"
18#include "ps2gl/metrics.h"
19#include "ps2gl/texture.h"
21#include "vu1_mem_linear.h"
25 int wordsPerVert = block.GetWordsPerVertex();
26 int wordsPerNormal = (block.GetNormalsAreValid()) ? block.GetWordsPerNormal() : 0;
27 int wordsPerTex = (block.GetTexCoordsAreValid()) ? block.GetWordsPerTexCoord() : 0;
28 int wordsPerColor = (block.GetColorsAreValid()) ? block.GetWordsPerColor() : 0;
30 CVifSCDmaPacket& packet = pGLContext->GetVif1Packet();
31 InitXferBlock(packet, wordsPerVert, wordsPerNormal, wordsPerTex, wordsPerColor);
36 int maxUnpackVerts = 256;
38 int vu1QuadsPerVert = InputQuadsPerVert;
39 int inputBufSize = InputGeomBufSize;
40 int maxVu1VertsPerBuffer = inputBufSize / vu1QuadsPerVert;
42 int maxVertsPerBuffer = Math::Min(maxUnpackVerts, maxVu1VertsPerBuffer);
43 maxVertsPerBuffer -= 3;
45 maxVertsPerBuffer -= maxVertsPerBuffer % block.GetNumVertsPerPrim();
49 DrawBlock(packet, block, maxVertsPerBuffer);
55 CVifSCDmaPacket& packet = glContext.GetVif1Packet();
59 AddVu1RendererContext(packet, primType, kContextStart);
64 packet.Base(kDoubleBufBase);
65 packet.Offset(kDoubleBufOffset);
75 return Math::Max(geometry.GetTotalVertices() / 70, 1) * 1000;
85 deps.PerVtxMaterial = 1;
92 return !(pGLContext->GetImmLighting().GetLightingEnabled()
93 && !geometry.GetNormalsAreValid());
96void CLinearRenderer::DrawBlock(CVifSCDmaPacket& packet,
99 mErrorIf(block.GetWordsPerVertex() == 2,
"2 word vertices not supported");
106 packet.Stcycl(1, InputQuadsPerVert);
118 bool stripsCanBeMerged = block.GetStripsCanBeMerged();
120 int numVertsXferred = 0;
121 int numStripsInBuffer = 0;
122 unsigned short stripOffsets[16];
123 bool haveContinued =
false;
124 const void *normals, *vertices, *texCoords, *colors;
125 normals = vertices = texCoords = colors = NULL;
126 int vu1BufferOffset = 0, stripIndex = 0, vertsInBlock = 0;
129 int adjMaxVertsPerBuffer = maxVertsPerBuffer - (Math::IsOdd(maxVertsPerBuffer - numVertsToRestart));
130 for (
int curStrip = 0; curStrip < block.GetNumStrips(); curStrip++) {
133 int numVertsFirstBuffer, numVertsLastBuffer, numBuffers;
134 FindNumBuffers(block.GetStripLength(curStrip),
135 numVertsToRestart, numVertsXferred, maxVertsPerBuffer,
136 numVertsFirstBuffer, numVertsLastBuffer, numBuffers);
142 int numVertsThisBuffer;
143 int indexIntoStrip = 0;
144 int vu1QuadsPerVert = InputQuadsPerVert;
145 for (
int curBuffer = 0;
146 curBuffer < numBuffers;
147 curBuffer++, indexIntoStrip += numVertsThisBuffer - numVertsToRestart) {
151 numVertsThisBuffer = numVertsFirstBuffer;
152 else if (curBuffer == numBuffers - 1)
153 numVertsThisBuffer = numVertsLastBuffer;
155 numVertsThisBuffer = adjMaxVertsPerBuffer;
159 if (!haveContinued) {
160 vertices = (block.GetVerticesAreValid()) ? block.GetVertices(curStrip) : NULL;
161 normals = (block.GetNormalsAreValid()) ? block.GetNormals(curStrip) : NULL;
162 texCoords = (block.GetTexCoordsAreValid()) ? block.GetTexCoords(curStrip) : NULL;
163 colors = (block.GetColorsAreValid()) ? block.GetColors(curStrip) : NULL;
164 vu1BufferOffset = InputGeomOffset + numVertsXferred * vu1QuadsPerVert;
165 stripIndex = indexIntoStrip;
175 if (!block.StripIsContinued(curStrip)
176 || curBuffer < numBuffers - 1) {
178 vertices, normals, texCoords, colors,
180 stripIndex, vertsInBlock + numVertsThisBuffer);
181 haveContinued =
false;
183 vertsInBlock += numVertsThisBuffer;
184 haveContinued =
true;
187 stripOffsets[numStripsInBuffer++] = numVertsXferred;
188 mErrorIf(numStripsInBuffer > 16,
"Too many strips in buffer.. this shouldn't happen");
189 numVertsXferred += numVertsThisBuffer;
192 if (curBuffer < numBuffers - 1) {
193 FinishBuffer(packet, numVertsToRestart, numVertsXferred, vu1QuadsPerVert,
194 numStripsInBuffer, stripOffsets);
195 numStripsInBuffer = 0;
210 if (!stripsCanBeMerged
211 || ((maxVertsPerBuffer - numVertsXferred) <= numVertsToRestart + 1)
212 || numStripsInBuffer == 16
213 || (curStrip == block.GetNumStrips() - 1)) {
216 vertices, normals, texCoords, colors,
218 stripIndex, vertsInBlock);
219 haveContinued =
false;
222 FinishBuffer(packet, numVertsToRestart, numVertsXferred, vu1QuadsPerVert,
223 numStripsInBuffer, stripOffsets);
224 numStripsInBuffer = 0;
231void CLinearRenderer::FinishBuffer(CVifSCDmaPacket& packet,
int numVertsToBreakStrip,
232 int numVertsInBuffer,
int vu1QuadsPerVert,
233 int numStripsInBuffer,
unsigned short* stripOffsets)
239 XferBufferHeader(packet, numVertsToBreakStrip,
241 numStripsInBuffer, stripOffsets);
249void CLinearRenderer::FindNumBuffers(
int numToAdd,
int numVertsToRestart,
250 int numVertsAlreadyInFirstBuffer,
int maxVertsPerBuffer,
251 int& numVertsFirstBuffer,
int& numVertsLastBuffer,
258 int freeVertsFirstBuffer = maxVertsPerBuffer - numVertsAlreadyInFirstBuffer;
259 if (numToAdd <= freeVertsFirstBuffer) {
260 numVertsFirstBuffer = numToAdd;
266 numVertsFirstBuffer = freeVertsFirstBuffer - (int)Math::IsOdd(freeVertsFirstBuffer);
267 numLeftToAdd = numToAdd - (numVertsFirstBuffer - numVertsToRestart);
270 int adjVertsPerBuffer = maxVertsPerBuffer - numVertsToRestart;
271 adjVertsPerBuffer -= (int)Math::IsOdd(adjVertsPerBuffer);
272 numBuffers = 1 + numLeftToAdd / adjVertsPerBuffer;
273 if (numLeftToAdd % adjVertsPerBuffer > numVertsToRestart)
276 numVertsLastBuffer = (numBuffers > 1)
277 ? numToAdd - ((numVertsFirstBuffer - numVertsToRestart)
278 + (numBuffers - 2) * adjVertsPerBuffer)
282void CLinearRenderer::XferBufferHeader(CVifSCDmaPacket& packet,
283 int numVertsToBreakStrip,
285 int numStripsInBuffer,
unsigned short* stripOffsets)
287 int vu1OutQuadsPerVert = OutputQuadsPerVert;
291 packet.OpenUnpack(Vifs::UnpackModes::v4_32, 0, Packet::kDoubleBuff);
303 unsigned int adcBits = 0;
304 if (numVertsToBreakStrip == 0)
305 numStripsInBuffer = 0;
306 else if (numVertsToBreakStrip == 2)
310 unsigned int stopBit = 0x400;
311 for (
int i = 0; i < 16; i++) {
312 if (i < numStripsInBuffer)
313 adc = (float)(adcBits | (
unsigned int)stripOffsets[i] * vu1OutQuadsPerVert);
314 else if (i == numStripsInBuffer)
315 adc = (float)stopBit;
321 packet.CloseUnpack();
324 packet.Stcycl(1, InputQuadsPerVert);
void XferBlock(CVifSCDmaPacket &packet, const void *vertices, const void *normals, const void *texCoords, const void *colors, int vu1Offset, int firstElement, int numToAdd)
void InitXferBlock(CVifSCDmaPacket &packet, int wordsPerVertex, int wordsPerNormal, int wordsPerTex, int wordsPerColor)
int GetNumVertsToRestartStrip()
virtual void InitContext(GLenum primType, tU32 rcChanges, bool userRcChanged)
virtual int GetPacketQwordSize(const CGeometryBlock &geometry)
virtual CRendererProps GetRenderContextDeps()
virtual bool GetCachePackets(const CGeometryBlock &geometry)
virtual void DrawLinearArrays(CGeometryBlock &block)
Draw arrays of vertices that are accessed linearly (i.e., glDrawArrays)