|
|
1.1 root 1: //
2: // r_drawa.s
3: // x86 assembly-language edge clipping and emission code
4: //
5:
6: #include "qasm.h"
7: #include "d_ifacea.h"
8:
9: #if id386
10:
11: // !!! if these are changed, they must be changed in r_draw.c too !!!
12: #define FULLY_CLIPPED_CACHED 0x80000000
13: #define FRAMECOUNT_MASK 0x7FFFFFFF
14:
15: .data
16:
17: Ld0: .single 0.0
18: Ld1: .single 0.0
19: Lstack: .long 0
20: Lfp_near_clip: .single NEAR_CLIP
21: Lceilv0: .long 0
22: Lv: .long 0
23: Lu0: .long 0
24: Lv0: .long 0
25: Lzi0: .long 0
26:
27: .text
28:
29: //----------------------------------------------------------------------
30: // edge clipping code
31: //----------------------------------------------------------------------
32:
33: #define pv0 4+12
34: #define pv1 8+12
35: #define clip 12+12
36:
37: .align 4
38: .globl C(R_ClipEdge)
39: C(R_ClipEdge):
40: pushl %esi // preserve register variables
41: pushl %edi
42: pushl %ebx
43: movl %esp,Lstack // for clearing the stack later
44:
45: // float d0, d1, f;
46: // mvertex_t clipvert;
47:
48: movl clip(%esp),%ebx
49: movl pv0(%esp),%esi
50: movl pv1(%esp),%edx
51:
52: // if (clip)
53: // {
54: testl %ebx,%ebx
55: jz Lemit
56:
57: // do
58: // {
59:
60: Lcliploop:
61:
62: // d0 = DotProduct (pv0->position, clip->normal) - clip->dist;
63: // d1 = DotProduct (pv1->position, clip->normal) - clip->dist;
64: flds mv_position+0(%esi)
65: fmuls cp_normal+0(%ebx)
66: flds mv_position+4(%esi)
67: fmuls cp_normal+4(%ebx)
68: flds mv_position+8(%esi)
69: fmuls cp_normal+8(%ebx)
70: fxch %st(1)
71: faddp %st(0),%st(2) // d0mul2 | d0add0
72:
73: flds mv_position+0(%edx)
74: fmuls cp_normal+0(%ebx)
75: flds mv_position+4(%edx)
76: fmuls cp_normal+4(%ebx)
77: flds mv_position+8(%edx)
78: fmuls cp_normal+8(%ebx)
79: fxch %st(1)
80: faddp %st(0),%st(2) // d1mul2 | d1add0 | d0mul2 | d0add0
81: fxch %st(3) // d0add0 | d1add0 | d0mul2 | d1mul2
82:
83: faddp %st(0),%st(2) // d1add0 | dot0 | d1mul2
84: faddp %st(0),%st(2) // dot0 | dot1
85:
86: fsubs cp_dist(%ebx) // d0 | dot1
87: fxch %st(1) // dot1 | d0
88: fsubs cp_dist(%ebx) // d1 | d0
89: fxch %st(1)
90: fstps Ld0
91: fstps Ld1
92:
93: // if (d0 >= 0)
94: // {
95: movl Ld0,%eax
96: movl Ld1,%ecx
97: orl %eax,%ecx
98: js Lp2
99:
100: // both points are unclipped
101:
102: Lcontinue:
103:
104: //
105: // R_ClipEdge (&clipvert, pv1, clip->next);
106: // return;
107: // }
108: // } while ((clip = clip->next) != NULL);
109: movl cp_next(%ebx),%ebx
110: testl %ebx,%ebx
111: jnz Lcliploop
112:
113: // }
114:
115: //// add the edge
116: // R_EmitEdge (pv0, pv1);
117: Lemit:
118:
119: //
120: // set integer rounding to ceil mode, set to single precision
121: //
122: // FIXME: do away with by manually extracting integers from floats?
123: // FIXME: set less often
124: fldcw ceil_cw
125:
126: // edge_t *edge, *pcheck;
127: // int u_check;
128: // float u, u_step;
129: // vec3_t local, transformed;
130: // float *world;
131: // int v, v2, ceilv0;
132: // float scale, lzi0, u0, v0;
133: // int side;
134:
135: // if (r_lastvertvalid)
136: // {
137: cmpl $0,C(r_lastvertvalid)
138: jz LCalcFirst
139:
140: // u0 = r_u1;
141: // v0 = r_v1;
142: // lzi0 = r_lzi1;
143: // ceilv0 = r_ceilv1;
144: movl C(r_lzi1),%eax
145: movl C(r_u1),%ecx
146: movl %eax,Lzi0
147: movl %ecx,Lu0
148: movl C(r_v1),%ecx
149: movl C(r_ceilv1),%eax
150: movl %ecx,Lv0
151: movl %eax,Lceilv0
152: jmp LCalcSecond
153:
154: // }
155:
156: LCalcFirst:
157:
158: // else
159: // {
160: // world = &pv0->position[0];
161:
162: call LTransformAndProject // v0 | lzi0 | u0
163:
164: fsts Lv0
165: fxch %st(2) // u0 | lzi0 | v0
166: fstps Lu0 // lzi0 | v0
167: fstps Lzi0 // v0
168:
169: // ceilv0 = (int)(v0 - 2000) + 2000; // ceil(v0);
170: fistpl Lceilv0
171:
172: // }
173:
174: LCalcSecond:
175:
176: // world = &pv1->position[0];
177: movl %edx,%esi
178:
179: call LTransformAndProject // v1 | lzi1 | u1
180:
181: flds Lu0 // u0 | v1 | lzi1 | u1
182: fxch %st(3) // u1 | v1 | lzi1 | u0
183: flds Lzi0 // lzi0 | u1 | v1 | lzi1 | u0
184: fxch %st(3) // lzi1 | u1 | v1 | lzi0 | u0
185: flds Lv0 // v0 | lzi1 | u1 | v1 | lzi0 | u0
186: fxch %st(3) // v1 | lzi1 | u1 | v0 | lzi0 | u0
187:
188: // r_ceilv1 = (int)(r_v1 - 2000) + 2000; // ceil(r_v1);
189: fistl C(r_ceilv1)
190:
191: fldcw single_cw // put back normal floating-point state
192:
193: fsts C(r_v1)
194: fxch %st(4) // lzi0 | lzi1 | u1 | v0 | v1 | u0
195:
196: // if (r_lzi1 > lzi0)
197: // lzi0 = r_lzi1;
198: fcom %st(1)
199: fnstsw %ax
200: testb $1,%ah
201: jz LP0
202: fstp %st(0)
203: fld %st(0)
204: LP0:
205:
206: fxch %st(1) // lzi1 | lzi0 | u1 | v0 | v1 | u0
207: fstps C(r_lzi1) // lzi0 | u1 | v0 | v1 | u0
208: fxch %st(1)
209: fsts C(r_u1)
210: fxch %st(1)
211:
212: // if (lzi0 > r_nearzi) // for mipmap finding
213: // r_nearzi = lzi0;
214: fcoms C(r_nearzi)
215: fnstsw %ax
216: testb $0x45,%ah
217: jnz LP1
218: fsts C(r_nearzi)
219: LP1:
220:
221: // // for right edges, all we want is the effect on 1/z
222: // if (r_nearzionly)
223: // return;
224: movl C(r_nearzionly),%eax
225: testl %eax,%eax
226: jz LP2
227: LPop5AndDone:
228: movl C(cacheoffset),%eax
229: movl C(r_framecount),%edx
230: cmpl $0x7FFFFFFF,%eax
231: jz LDoPop
232: andl $(FRAMECOUNT_MASK),%edx
233: orl $(FULLY_CLIPPED_CACHED),%edx
234: movl %edx,C(cacheoffset)
235:
236: LDoPop:
237: fstp %st(0) // u1 | v0 | v1 | u0
238: fstp %st(0) // v0 | v1 | u0
239: fstp %st(0) // v1 | u0
240: fstp %st(0) // u0
241: fstp %st(0)
242: jmp Ldone
243:
244: LP2:
245:
246: // // create the edge
247: // if (ceilv0 == r_ceilv1)
248: // return; // horizontal edge
249: movl Lceilv0,%ebx
250: movl C(edge_p),%edi
251: movl C(r_ceilv1),%ecx
252: movl %edi,%edx
253: movl C(r_pedge),%esi
254: addl $(et_size),%edx
255: cmpl %ecx,%ebx
256: jz LPop5AndDone
257:
258: movl C(r_pedge),%eax
259: movl %eax,et_owner(%edi)
260:
261: // side = ceilv0 > r_ceilv1;
262: //
263: // edge->nearzi = lzi0;
264: fstps et_nearzi(%edi) // u1 | v0 | v1 | u0
265:
266: // if (side == 1)
267: // {
268: jc LSide0
269:
270: LSide1:
271:
272: // // leading edge (go from p2 to p1)
273:
274: // u_step = ((u0 - r_u1) / (v0 - r_v1));
275: fsubrp %st(0),%st(3) // v0 | v1 | u0-u1
276: fsub %st(1),%st(0) // v0-v1 | v1 | u0-u1
277: fdivrp %st(0),%st(2) // v1 | ustep
278:
279: // r_emitted = 1;
280: movl $1,C(r_emitted)
281:
282: // edge = edge_p++;
283: movl %edx,C(edge_p)
284:
285: // pretouch next edge
286: movl (%edx),%eax
287:
288: // v2 = ceilv0 - 1;
289: // v = r_ceilv1;
290: movl %ecx,%eax
291: leal -1(%ebx),%ecx
292: movl %eax,%ebx
293:
294: // edge->surfs[0] = 0;
295: // edge->surfs[1] = surface_p - surfaces;
296: movl C(surface_p),%eax
297: movl C(surfaces),%esi
298: subl %edx,%edx
299: subl %esi,%eax
300: shrl $(SURF_T_SHIFT),%eax
301: movl %edx,et_surfs(%edi)
302: movl %eax,et_surfs+2(%edi)
303:
304: subl %esi,%esi
305:
306: // u = r_u1 + ((float)v - r_v1) * u_step;
307: movl %ebx,Lv
308: fildl Lv // v | v1 | ustep
309: fsubp %st(0),%st(1) // v-v1 | ustep
310: fmul %st(1),%st(0) // (v-v1)*ustep | ustep
311: fadds C(r_u1) // u | ustep
312:
313: jmp LSideDone
314:
315: // }
316:
317: LSide0:
318:
319: // else
320: // {
321: // // trailing edge (go from p1 to p2)
322:
323: // u_step = ((r_u1 - u0) / (r_v1 - v0));
324: fsub %st(3),%st(0) // u1-u0 | v0 | v1 | u0
325: fxch %st(2) // v1 | v0 | u1-u0 | u0
326: fsub %st(1),%st(0) // v1-v0 | v0 | u1-u0 | u0
327: fdivrp %st(0),%st(2) // v0 | ustep | u0
328:
329: // r_emitted = 1;
330: movl $1,C(r_emitted)
331:
332: // edge = edge_p++;
333: movl %edx,C(edge_p)
334:
335: // pretouch next edge
336: movl (%edx),%eax
337:
338: // v = ceilv0;
339: // v2 = r_ceilv1 - 1;
340: decl %ecx
341:
342: // edge->surfs[0] = surface_p - surfaces;
343: // edge->surfs[1] = 0;
344: movl C(surface_p),%eax
345: movl C(surfaces),%esi
346: subl %edx,%edx
347: subl %esi,%eax
348: shrl $(SURF_T_SHIFT),%eax
349: movl %edx,et_surfs+2(%edi)
350: movl %eax,et_surfs(%edi)
351:
352: movl $1,%esi
353:
354: // u = u0 + ((float)v - v0) * u_step;
355: movl %ebx,Lv
356: fildl Lv // v | v0 | ustep | u0
357: fsubp %st(0),%st(1) // v-v0 | ustep | u0
358: fmul %st(1),%st(0) // (v-v0)*ustep | ustep | u0
359: faddp %st(0),%st(2) // ustep | u
360: fxch %st(1) // u | ustep
361:
362: // }
363:
364: LSideDone:
365:
366: // edge->u_step = u_step*0x100000;
367: // edge->u = u*0x100000 + 0xFFFFF;
368:
369: fmuls fp_1m // u*0x100000 | ustep
370: fxch %st(1) // ustep | u*0x100000
371: fmuls fp_1m // ustep*0x100000 | u*0x100000
372: fxch %st(1) // u*0x100000 | ustep*0x100000
373: fadds fp_1m_minus_1 // u*0x100000 + 0xFFFFF | ustep*0x100000
374: fxch %st(1) // ustep*0x100000 | u*0x100000 + 0xFFFFF
375: fistpl et_u_step(%edi) // u*0x100000 + 0xFFFFF
376: fistpl et_u(%edi)
377:
378: // // we need to do this to avoid stepping off the edges if a very nearly
379: // // horizontal edge is less than epsilon above a scan, and numeric error
380: // // causes it to incorrectly extend to the scan, and the extension of the
381: // // line goes off the edge of the screen
382: // // FIXME: is this actually needed?
383: // if (edge->u < r_refdef.vrect_x_adj_shift20)
384: // edge->u = r_refdef.vrect_x_adj_shift20;
385: // if (edge->u > r_refdef.vrectright_adj_shift20)
386: // edge->u = r_refdef.vrectright_adj_shift20;
387: movl et_u(%edi),%eax
388: movl C(r_refdef)+rd_vrect_x_adj_shift20,%edx
389: cmpl %edx,%eax
390: jl LP4
391: movl C(r_refdef)+rd_vrectright_adj_shift20,%edx
392: cmpl %edx,%eax
393: jng LP5
394: LP4:
395: movl %edx,et_u(%edi)
396: movl %edx,%eax
397: LP5:
398:
399: // // sort the edge in normally
400: // u_check = edge->u;
401: //
402: // if (edge->surfs[0])
403: // u_check++; // sort trailers after leaders
404: addl %esi,%eax
405:
406: // if (!newedges[v] || newedges[v]->u >= u_check)
407: // {
408: movl C(newedges)(,%ebx,4),%esi
409: testl %esi,%esi
410: jz LDoFirst
411: cmpl %eax,et_u(%esi)
412: jl LNotFirst
413: LDoFirst:
414:
415: // edge->next = newedges[v];
416: // newedges[v] = edge;
417: movl %esi,et_next(%edi)
418: movl %edi,C(newedges)(,%ebx,4)
419:
420: jmp LSetRemove
421:
422: // }
423:
424: LNotFirst:
425:
426: // else
427: // {
428: // pcheck = newedges[v];
429: //
430: // while (pcheck->next && pcheck->next->u < u_check)
431: // pcheck = pcheck->next;
432: LFindInsertLoop:
433: movl %esi,%edx
434: movl et_next(%esi),%esi
435: testl %esi,%esi
436: jz LInsertFound
437: cmpl %eax,et_u(%esi)
438: jl LFindInsertLoop
439:
440: LInsertFound:
441:
442: // edge->next = pcheck->next;
443: // pcheck->next = edge;
444: movl %esi,et_next(%edi)
445: movl %edi,et_next(%edx)
446:
447: // }
448:
449: LSetRemove:
450:
451: // edge->nextremove = removeedges[v2];
452: // removeedges[v2] = edge;
453: movl C(removeedges)(,%ecx,4),%eax
454: movl %edi,C(removeedges)(,%ecx,4)
455: movl %eax,et_nextremove(%edi)
456:
457: Ldone:
458: movl Lstack,%esp // clear temporary variables from stack
459:
460: popl %ebx // restore register variables
461: popl %edi
462: popl %esi
463: ret
464:
465: // at least one point is clipped
466:
467: Lp2:
468: testl %eax,%eax
469: jns Lp1
470:
471: // else
472: // {
473: // // point 0 is clipped
474:
475: // if (d1 < 0)
476: // {
477: movl Ld1,%eax
478: testl %eax,%eax
479: jns Lp3
480:
481: // // both points are clipped
482: // // we do cache fully clipped edges
483: // if (!leftclipped)
484: movl C(r_leftclipped),%eax
485: movl C(r_pedge),%ecx
486: testl %eax,%eax
487: jnz Ldone
488:
489: // r_pedge->framecount = r_framecount;
490: movl C(r_framecount),%eax
491: andl $(FRAMECOUNT_MASK),%eax
492: orl $(FULLY_CLIPPED_CACHED),%eax
493: movl %eax,C(cacheoffset)
494:
495: // return;
496: jmp Ldone
497:
498: // }
499:
500: Lp1:
501:
502: // // point 0 is unclipped
503: // if (d1 >= 0)
504: // {
505: // // both points are unclipped
506: // continue;
507:
508: // // only point 1 is clipped
509:
510: // f = d0 / (d0 - d1);
511: flds Ld0
512: flds Ld1
513: fsubr %st(1),%st(0)
514:
515: // // we don't cache partially clipped edges
516: movl $0x7FFFFFFF,C(cacheoffset)
517:
518: fdivrp %st(0),%st(1)
519:
520: subl $(mv_size),%esp // allocate space for clipvert
521:
522: // clipvert.position[0] = pv0->position[0] +
523: // f * (pv1->position[0] - pv0->position[0]);
524: // clipvert.position[1] = pv0->position[1] +
525: // f * (pv1->position[1] - pv0->position[1]);
526: // clipvert.position[2] = pv0->position[2] +
527: // f * (pv1->position[2] - pv0->position[2]);
528: flds mv_position+8(%edx)
529: fsubs mv_position+8(%esi)
530: flds mv_position+4(%edx)
531: fsubs mv_position+4(%esi)
532: flds mv_position+0(%edx)
533: fsubs mv_position+0(%esi) // 0 | 1 | 2
534:
535: // replace pv1 with the clip point
536: movl %esp,%edx
537: movl cp_leftedge(%ebx),%eax
538: testb %al,%al
539:
540: fmul %st(3),%st(0)
541: fxch %st(1) // 1 | 0 | 2
542: fmul %st(3),%st(0)
543: fxch %st(2) // 2 | 0 | 1
544: fmulp %st(0),%st(3) // 0 | 1 | 2
545: fadds mv_position+0(%esi)
546: fxch %st(1) // 1 | 0 | 2
547: fadds mv_position+4(%esi)
548: fxch %st(2) // 2 | 0 | 1
549: fadds mv_position+8(%esi)
550: fxch %st(1) // 0 | 2 | 1
551: fstps mv_position+0(%esp) // 2 | 1
552: fstps mv_position+8(%esp) // 1
553: fstps mv_position+4(%esp)
554:
555: // if (clip->leftedge)
556: // {
557: jz Ltestright
558:
559: // r_leftclipped = true;
560: // r_leftexit = clipvert;
561: movl $1,C(r_leftclipped)
562: movl mv_position+0(%esp),%eax
563: movl %eax,C(r_leftexit)+mv_position+0
564: movl mv_position+4(%esp),%eax
565: movl %eax,C(r_leftexit)+mv_position+4
566: movl mv_position+8(%esp),%eax
567: movl %eax,C(r_leftexit)+mv_position+8
568:
569: jmp Lcontinue
570:
571: // }
572:
573: Ltestright:
574: // else if (clip->rightedge)
575: // {
576: testb %ah,%ah
577: jz Lcontinue
578:
579: // r_rightclipped = true;
580: // r_rightexit = clipvert;
581: movl $1,C(r_rightclipped)
582: movl mv_position+0(%esp),%eax
583: movl %eax,C(r_rightexit)+mv_position+0
584: movl mv_position+4(%esp),%eax
585: movl %eax,C(r_rightexit)+mv_position+4
586: movl mv_position+8(%esp),%eax
587: movl %eax,C(r_rightexit)+mv_position+8
588:
589: // }
590: //
591: // R_ClipEdge (pv0, &clipvert, clip->next);
592: // return;
593: // }
594: jmp Lcontinue
595:
596: // }
597:
598: Lp3:
599:
600: // // only point 0 is clipped
601: // r_lastvertvalid = false;
602:
603: movl $0,C(r_lastvertvalid)
604:
605: // f = d0 / (d0 - d1);
606: flds Ld0
607: flds Ld1
608: fsubr %st(1),%st(0)
609:
610: // // we don't cache partially clipped edges
611: movl $0x7FFFFFFF,C(cacheoffset)
612:
613: fdivrp %st(0),%st(1)
614:
615: subl $(mv_size),%esp // allocate space for clipvert
616:
617: // clipvert.position[0] = pv0->position[0] +
618: // f * (pv1->position[0] - pv0->position[0]);
619: // clipvert.position[1] = pv0->position[1] +
620: // f * (pv1->position[1] - pv0->position[1]);
621: // clipvert.position[2] = pv0->position[2] +
622: // f * (pv1->position[2] - pv0->position[2]);
623: flds mv_position+8(%edx)
624: fsubs mv_position+8(%esi)
625: flds mv_position+4(%edx)
626: fsubs mv_position+4(%esi)
627: flds mv_position+0(%edx)
628: fsubs mv_position+0(%esi) // 0 | 1 | 2
629:
630: movl cp_leftedge(%ebx),%eax
631: testb %al,%al
632:
633: fmul %st(3),%st(0)
634: fxch %st(1) // 1 | 0 | 2
635: fmul %st(3),%st(0)
636: fxch %st(2) // 2 | 0 | 1
637: fmulp %st(0),%st(3) // 0 | 1 | 2
638: fadds mv_position+0(%esi)
639: fxch %st(1) // 1 | 0 | 2
640: fadds mv_position+4(%esi)
641: fxch %st(2) // 2 | 0 | 1
642: fadds mv_position+8(%esi)
643: fxch %st(1) // 0 | 2 | 1
644: fstps mv_position+0(%esp) // 2 | 1
645: fstps mv_position+8(%esp) // 1
646: fstps mv_position+4(%esp)
647:
648: // replace pv0 with the clip point
649: movl %esp,%esi
650:
651: // if (clip->leftedge)
652: // {
653: jz Ltestright2
654:
655: // r_leftclipped = true;
656: // r_leftenter = clipvert;
657: movl $1,C(r_leftclipped)
658: movl mv_position+0(%esp),%eax
659: movl %eax,C(r_leftenter)+mv_position+0
660: movl mv_position+4(%esp),%eax
661: movl %eax,C(r_leftenter)+mv_position+4
662: movl mv_position+8(%esp),%eax
663: movl %eax,C(r_leftenter)+mv_position+8
664:
665: jmp Lcontinue
666:
667: // }
668:
669: Ltestright2:
670: // else if (clip->rightedge)
671: // {
672: testb %ah,%ah
673: jz Lcontinue
674:
675: // r_rightclipped = true;
676: // r_rightenter = clipvert;
677: movl $1,C(r_rightclipped)
678: movl mv_position+0(%esp),%eax
679: movl %eax,C(r_rightenter)+mv_position+0
680: movl mv_position+4(%esp),%eax
681: movl %eax,C(r_rightenter)+mv_position+4
682: movl mv_position+8(%esp),%eax
683: movl %eax,C(r_rightenter)+mv_position+8
684:
685: // }
686: jmp Lcontinue
687:
688: // %esi = vec3_t point to transform and project
689: // %edx preserved
690: LTransformAndProject:
691:
692: // // transform and project
693: // VectorSubtract (world, modelorg, local);
694: flds mv_position+0(%esi)
695: fsubs C(modelorg)+0
696: flds mv_position+4(%esi)
697: fsubs C(modelorg)+4
698: flds mv_position+8(%esi)
699: fsubs C(modelorg)+8
700: fxch %st(2) // local[0] | local[1] | local[2]
701:
702: // TransformVector (local, transformed);
703: //
704: // if (transformed[2] < NEAR_CLIP)
705: // transformed[2] = NEAR_CLIP;
706: //
707: // lzi0 = 1.0 / transformed[2];
708: fld %st(0) // local[0] | local[0] | local[1] | local[2]
709: fmuls C(vpn)+0 // zm0 | local[0] | local[1] | local[2]
710: fld %st(1) // local[0] | zm0 | local[0] | local[1] |
711: // local[2]
712: fmuls C(vright)+0 // xm0 | zm0 | local[0] | local[1] | local[2]
713: fxch %st(2) // local[0] | zm0 | xm0 | local[1] | local[2]
714: fmuls C(vup)+0 // ym0 | zm0 | xm0 | local[1] | local[2]
715: fld %st(3) // local[1] | ym0 | zm0 | xm0 | local[1] |
716: // local[2]
717: fmuls C(vpn)+4 // zm1 | ym0 | zm0 | xm0 | local[1] |
718: // local[2]
719: fld %st(4) // local[1] | zm1 | ym0 | zm0 | xm0 |
720: // local[1] | local[2]
721: fmuls C(vright)+4 // xm1 | zm1 | ym0 | zm0 | xm0 |
722: // local[1] | local[2]
723: fxch %st(5) // local[1] | zm1 | ym0 | zm0 | xm0 |
724: // xm1 | local[2]
725: fmuls C(vup)+4 // ym1 | zm1 | ym0 | zm0 | xm0 |
726: // xm1 | local[2]
727: fxch %st(1) // zm1 | ym1 | ym0 | zm0 | xm0 |
728: // xm1 | local[2]
729: faddp %st(0),%st(3) // ym1 | ym0 | zm2 | xm0 | xm1 | local[2]
730: fxch %st(3) // xm0 | ym0 | zm2 | ym1 | xm1 | local[2]
731: faddp %st(0),%st(4) // ym0 | zm2 | ym1 | xm2 | local[2]
732: faddp %st(0),%st(2) // zm2 | ym2 | xm2 | local[2]
733: fld %st(3) // local[2] | zm2 | ym2 | xm2 | local[2]
734: fmuls C(vpn)+8 // zm3 | zm2 | ym2 | xm2 | local[2]
735: fld %st(4) // local[2] | zm3 | zm2 | ym2 | xm2 | local[2]
736: fmuls C(vright)+8 // xm3 | zm3 | zm2 | ym2 | xm2 | local[2]
737: fxch %st(5) // local[2] | zm3 | zm2 | ym2 | xm2 | xm3
738: fmuls C(vup)+8 // ym3 | zm3 | zm2 | ym2 | xm2 | xm3
739: fxch %st(1) // zm3 | ym3 | zm2 | ym2 | xm2 | xm3
740: faddp %st(0),%st(2) // ym3 | zm4 | ym2 | xm2 | xm3
741: fxch %st(4) // xm3 | zm4 | ym2 | xm2 | ym3
742: faddp %st(0),%st(3) // zm4 | ym2 | xm4 | ym3
743: fxch %st(1) // ym2 | zm4 | xm4 | ym3
744: faddp %st(0),%st(3) // zm4 | xm4 | ym4
745:
746: fcoms Lfp_near_clip
747: fnstsw %ax
748: testb $1,%ah
749: jz LNoClip
750: fstp %st(0)
751: flds Lfp_near_clip
752:
753: LNoClip:
754:
755: fdivrs float_1 // lzi0 | x | y
756: fxch %st(1) // x | lzi0 | y
757:
758: // // FIXME: build x/yscale into transform?
759: // scale = xscale * lzi0;
760: // u0 = (xcenter + scale*transformed[0]);
761: flds C(xscale) // xscale | x | lzi0 | y
762: fmul %st(2),%st(0) // scale | x | lzi0 | y
763: fmulp %st(0),%st(1) // scale*x | lzi0 | y
764: fadds C(xcenter) // u0 | lzi0 | y
765:
766: // if (u0 < r_refdef.fvrectx_adj)
767: // u0 = r_refdef.fvrectx_adj;
768: // if (u0 > r_refdef.fvrectright_adj)
769: // u0 = r_refdef.fvrectright_adj;
770: // FIXME: use integer compares of floats?
771: fcoms C(r_refdef)+rd_fvrectx_adj
772: fnstsw %ax
773: testb $1,%ah
774: jz LClampP0
775: fstp %st(0)
776: flds C(r_refdef)+rd_fvrectx_adj
777: LClampP0:
778: fcoms C(r_refdef)+rd_fvrectright_adj
779: fnstsw %ax
780: testb $0x45,%ah
781: jnz LClampP1
782: fstp %st(0)
783: flds C(r_refdef)+rd_fvrectright_adj
784: LClampP1:
785:
786: fld %st(1) // lzi0 | u0 | lzi0 | y
787:
788: // scale = yscale * lzi0;
789: // v0 = (ycenter - scale*transformed[1]);
790: fmuls C(yscale) // scale | u0 | lzi0 | y
791: fmulp %st(0),%st(3) // u0 | lzi0 | scale*y
792: fxch %st(2) // scale*y | lzi0 | u0
793: fsubrs C(ycenter) // v0 | lzi0 | u0
794:
795: // if (v0 < r_refdef.fvrecty_adj)
796: // v0 = r_refdef.fvrecty_adj;
797: // if (v0 > r_refdef.fvrectbottom_adj)
798: // v0 = r_refdef.fvrectbottom_adj;
799: // FIXME: use integer compares of floats?
800: fcoms C(r_refdef)+rd_fvrecty_adj
801: fnstsw %ax
802: testb $1,%ah
803: jz LClampP2
804: fstp %st(0)
805: flds C(r_refdef)+rd_fvrecty_adj
806: LClampP2:
807: fcoms C(r_refdef)+rd_fvrectbottom_adj
808: fnstsw %ax
809: testb $0x45,%ah
810: jnz LClampP3
811: fstp %st(0)
812: flds C(r_refdef)+rd_fvrectbottom_adj
813: LClampP3:
814: ret
815:
816: #endif // id386
817:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.