void GSRendererDX9::SetupIA() { D3DPRIMITIVETYPE topology; switch(m_vt.m_primclass) { case GS_POINT_CLASS: topology = D3DPT_POINTLIST; break; case GS_LINE_CLASS: topology = D3DPT_LINELIST; if(PRIM->IIP == 0) { for(size_t i = 0, j = m_index.tail; i < j; i += 2) { uint32 tmp = m_index.buff[i + 0]; m_index.buff[i + 0] = m_index.buff[i + 1]; m_index.buff[i + 1] = tmp; } } break; case GS_TRIANGLE_CLASS: topology = D3DPT_TRIANGLELIST; if(PRIM->IIP == 0) { for(size_t i = 0, j = m_index.tail; i < j; i += 3) { uint32 tmp = m_index.buff[i + 0]; m_index.buff[i + 0] = m_index.buff[i + 2]; m_index.buff[i + 2] = tmp; } } break; case GS_SPRITE_CLASS: topology = D3DPT_TRIANGLELIST; // each sprite converted to quad needs twice the space while(m_vertex.tail * 2 > m_vertex.maxcount) { GrowVertexBuffer(); } // assume vertices are tightly packed and sequentially indexed (it should be the case) if(m_vertex.next >= 2) { size_t count = m_vertex.next; int i = (int)count * 2 - 4; GSVertex* s = &m_vertex.buff[count - 2]; GSVertex* q = &m_vertex.buff[count * 2 - 4]; uint32* RESTRICT index = &m_index.buff[count * 3 - 6]; for(; i >= 0; i -= 4, s -= 2, q -= 4, index -= 6) { GSVertex v0 = s[0]; GSVertex v1 = s[1]; v0.RGBAQ = v1.RGBAQ; v0.XYZ.Z = v1.XYZ.Z; v0.FOG = v1.FOG; q[0] = v0; q[3] = v1; // swap x, s, u uint16 x = v0.XYZ.X; v0.XYZ.X = v1.XYZ.X; v1.XYZ.X = x; float s = v0.ST.S; v0.ST.S = v1.ST.S; v1.ST.S = s; uint16 u = v0.U; v0.U = v1.U; v1.U = u; q[1] = v0; q[2] = v1; index[0] = i + 0; index[1] = i + 1; index[2] = i + 2; index[3] = i + 1; index[4] = i + 2; index[5] = i + 3; } m_vertex.head = m_vertex.tail = m_vertex.next = count * 2; m_index.tail = count * 3; } break; default: __assume(0); } GSDevice9* dev = (GSDevice9*)m_dev; (*dev)->SetRenderState(D3DRS_SHADEMODE, PRIM->IIP ? D3DSHADE_GOURAUD : D3DSHADE_FLAT); // TODO void* ptr = NULL; if(dev->IAMapVertexBuffer(&ptr, sizeof(GSVertexHW9), m_vertex.next)) { GSVertex* RESTRICT s = (GSVertex*)m_vertex.buff; GSVertexHW9* RESTRICT d = (GSVertexHW9*)ptr; for(uint32 i = 0; i < m_vertex.next; i++, s++, d++) { GSVector4 p = GSVector4(GSVector4i::load(s->XYZ.u32[0]).upl16()); if(PRIM->TME && !PRIM->FST) { p = p.xyxy(GSVector4((float)s->XYZ.Z, s->RGBAQ.Q)); } else { p = p.xyxy(GSVector4::load((float)s->XYZ.Z)); } GSVector4 t = GSVector4::zero(); if(PRIM->TME) { if(PRIM->FST) { if(UserHacks_WildHack && !isPackedUV_HackFlag) { t = GSVector4(GSVector4i::load(s->UV & 0x3FEF3FEF).upl16()); //printf("GSDX: %08X | D3D9(%d) %s\n", s->UV & 0x3FEF3FEF, m_vertex.next, i == 0 ? "*" : ""); } else { t = GSVector4(GSVector4i::load(s->UV).upl16()); } } else { t = GSVector4::loadl(&s->ST); } } t = t.xyxy(GSVector4::cast(GSVector4i(s->RGBAQ.u32[0], s->FOG))); d->p = p; d->t = t; } dev->IAUnmapVertexBuffer(); } dev->IASetIndexBuffer(m_index.buff, m_index.tail); dev->IASetPrimitiveTopology(topology); }
void GSRendererDX9::SetupIA(const float& sx, const float& sy) { D3DPRIMITIVETYPE topology; switch(m_vt.m_primclass) { case GS_POINT_CLASS: topology = D3DPT_POINTLIST; break; case GS_LINE_CLASS: topology = D3DPT_LINELIST; if(PRIM->IIP == 0) { for(size_t i = 0, j = m_index.tail; i < j; i += 2) { uint32 tmp = m_index.buff[i + 0]; m_index.buff[i + 0] = m_index.buff[i + 1]; m_index.buff[i + 1] = tmp; } } break; case GS_TRIANGLE_CLASS: topology = D3DPT_TRIANGLELIST; if(PRIM->IIP == 0) { for(size_t i = 0, j = m_index.tail; i < j; i += 3) { uint32 tmp = m_index.buff[i + 0]; m_index.buff[i + 0] = m_index.buff[i + 2]; m_index.buff[i + 2] = tmp; } } break; case GS_SPRITE_CLASS: topology = D3DPT_TRIANGLELIST; // each sprite converted to quad needs twice the space Lines2Sprites(); break; default: __assume(0); } GSDevice9* dev = (GSDevice9*)m_dev; (*dev)->SetRenderState(D3DRS_SHADEMODE, PRIM->IIP ? D3DSHADE_GOURAUD : D3DSHADE_FLAT); // TODO void* ptr = NULL; if(dev->IAMapVertexBuffer(&ptr, sizeof(GSVertexHW9), m_vertex.next)) { GSVertex* RESTRICT s = (GSVertex*)m_vertex.buff; GSVertexHW9* RESTRICT d = (GSVertexHW9*)ptr; for(uint32 i = 0; i < m_vertex.next; i++, s++, d++) { GSVector4 p = GSVector4(GSVector4i::load(s->XYZ.u32[0]).upl16()); if(PRIM->TME && !PRIM->FST) { p = p.xyxy(GSVector4((float)s->XYZ.Z, s->RGBAQ.Q)); } else { p = p.xyxy(GSVector4::load((float)s->XYZ.Z)); } GSVector4 t = GSVector4::zero(); if(PRIM->TME) { if(PRIM->FST) { if(UserHacks_WildHack && !isPackedUV_HackFlag) { t = GSVector4(GSVector4i::load(s->UV & 0x3FEF3FEF).upl16()); //printf("GSDX: %08X | D3D9(%d) %s\n", s->UV & 0x3FEF3FEF, m_vertex.next, i == 0 ? "*" : ""); } else { t = GSVector4(GSVector4i::load(s->UV).upl16()); } } else { t = GSVector4::loadl(&s->ST); } } t = t.xyxy(GSVector4::cast(GSVector4i(s->RGBAQ.u32[0], s->FOG))); d->p = p; d->t = t; } dev->IAUnmapVertexBuffer(); } dev->IASetIndexBuffer(m_index.buff, m_index.tail); dev->IASetPrimitiveTopology(topology); }