mirror of
https://gitlab.com/skmp/dca3-game.git
synced 2025-09-02 19:23:16 +02:00
im2d: strip -> fan, rwdc micro wins for memory
This commit is contained in:
@@ -271,13 +271,13 @@ CShadowCamera::InvertRaster()
|
|||||||
RwIm2DVertexSetIntRGBA (&vx[1], 255, 255, 255, 255);
|
RwIm2DVertexSetIntRGBA (&vx[1], 255, 255, 255, 255);
|
||||||
|
|
||||||
RwIm2DVertexSetScreenX (&vx[2], crw);
|
RwIm2DVertexSetScreenX (&vx[2], crw);
|
||||||
RwIm2DVertexSetScreenY (&vx[2], 0.0f);
|
RwIm2DVertexSetScreenY (&vx[2], crh);
|
||||||
RwIm2DVertexSetScreenZ (&vx[2], RwIm2DGetNearScreenZ());
|
RwIm2DVertexSetScreenZ (&vx[2], RwIm2DGetNearScreenZ());
|
||||||
RwIm2DVertexSetRecipCameraZ(&vx[2], recipZ);
|
RwIm2DVertexSetRecipCameraZ(&vx[2], recipZ);
|
||||||
RwIm2DVertexSetIntRGBA (&vx[2], 255, 255, 255, 255);
|
RwIm2DVertexSetIntRGBA (&vx[2], 255, 255, 255, 255);
|
||||||
|
|
||||||
RwIm2DVertexSetScreenX (&vx[3], crw);
|
RwIm2DVertexSetScreenX (&vx[3], crw);
|
||||||
RwIm2DVertexSetScreenY (&vx[3], crh);
|
RwIm2DVertexSetScreenY (&vx[3], 0.0f);
|
||||||
RwIm2DVertexSetScreenZ (&vx[3], RwIm2DGetNearScreenZ());
|
RwIm2DVertexSetScreenZ (&vx[3], RwIm2DGetNearScreenZ());
|
||||||
RwIm2DVertexSetRecipCameraZ(&vx[3], recipZ);
|
RwIm2DVertexSetRecipCameraZ(&vx[3], recipZ);
|
||||||
RwIm2DVertexSetIntRGBA (&vx[3], 255, 255, 255, 255);
|
RwIm2DVertexSetIntRGBA (&vx[3], 255, 255, 255, 255);
|
||||||
@@ -289,7 +289,7 @@ CShadowCamera::InvertRaster()
|
|||||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDINVDESTCOLOR);
|
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDINVDESTCOLOR);
|
||||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
|
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
|
||||||
|
|
||||||
RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx, 4);
|
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, vx, 4);
|
||||||
|
|
||||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
|
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
|
||||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
|
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
|
||||||
|
@@ -384,23 +384,23 @@ RwBool Im2DRenderQuad(RwReal x1, RwReal y1, RwReal x2, RwReal y2, RwReal z, RwRe
|
|||||||
RwIm2DVertexSetU(&vx[1], uvOffset, recipCamZ);
|
RwIm2DVertexSetU(&vx[1], uvOffset, recipCamZ);
|
||||||
RwIm2DVertexSetV(&vx[1], 1.0f + uvOffset, recipCamZ);
|
RwIm2DVertexSetV(&vx[1], 1.0f + uvOffset, recipCamZ);
|
||||||
|
|
||||||
RwIm2DVertexSetScreenX(&vx[2], x2);
|
RwIm2DVertexSetScreenX(&vx[2], x2);
|
||||||
RwIm2DVertexSetScreenY(&vx[2], y1);
|
RwIm2DVertexSetScreenY(&vx[2], y2);
|
||||||
RwIm2DVertexSetScreenZ(&vx[2], z);
|
RwIm2DVertexSetScreenZ(&vx[2], z);
|
||||||
RwIm2DVertexSetIntRGBA(&vx[2], 255, 255, 255, 255);
|
RwIm2DVertexSetIntRGBA(&vx[2], 255, 255, 255, 255);
|
||||||
RwIm2DVertexSetRecipCameraZ(&vx[2], recipCamZ);
|
RwIm2DVertexSetRecipCameraZ(&vx[2], recipCamZ);
|
||||||
RwIm2DVertexSetU(&vx[2], 1.0f + uvOffset, recipCamZ);
|
RwIm2DVertexSetU(&vx[2], 1.0f + uvOffset, recipCamZ);
|
||||||
RwIm2DVertexSetV(&vx[2], uvOffset, recipCamZ);
|
RwIm2DVertexSetV(&vx[2], 1.0f + uvOffset, recipCamZ);
|
||||||
|
|
||||||
RwIm2DVertexSetScreenX(&vx[3], x2);
|
RwIm2DVertexSetScreenX(&vx[3], x2);
|
||||||
RwIm2DVertexSetScreenY(&vx[3], y2);
|
RwIm2DVertexSetScreenY(&vx[3], y1);
|
||||||
RwIm2DVertexSetScreenZ(&vx[3], z);
|
RwIm2DVertexSetScreenZ(&vx[3], z);
|
||||||
RwIm2DVertexSetIntRGBA(&vx[3], 255, 255, 255, 255);
|
RwIm2DVertexSetIntRGBA(&vx[3], 255, 255, 255, 255);
|
||||||
RwIm2DVertexSetRecipCameraZ(&vx[3], recipCamZ);
|
RwIm2DVertexSetRecipCameraZ(&vx[3], recipCamZ);
|
||||||
RwIm2DVertexSetU(&vx[3], 1.0f + uvOffset, recipCamZ);
|
RwIm2DVertexSetU(&vx[3], 1.0f + uvOffset, recipCamZ);
|
||||||
RwIm2DVertexSetV(&vx[3], 1.0f + uvOffset, recipCamZ);
|
RwIm2DVertexSetV(&vx[3], uvOffset, recipCamZ);
|
||||||
|
|
||||||
RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx, 4);
|
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, vx, 4);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
486
vendor/librw/src/dc/rwdc.cpp
vendored
486
vendor/librw/src/dc/rwdc.cpp
vendored
@@ -674,7 +674,7 @@ struct atomic_context_t {
|
|||||||
bool global_needsNoClip;
|
bool global_needsNoClip;
|
||||||
bool skinMatrix0Identity;
|
bool skinMatrix0Identity;
|
||||||
|
|
||||||
matrix_t worldView, mtx;
|
matrix_t mtx;
|
||||||
UniformObject uniform;
|
UniformObject uniform;
|
||||||
};
|
};
|
||||||
/* END Ligting Structs and Defines */
|
/* END Ligting Structs and Defines */
|
||||||
@@ -934,6 +934,14 @@ struct chunked_vector {
|
|||||||
curr->header.used = 0;
|
curr->header.used = 0;
|
||||||
curr->header.free = chunk::item_count;
|
curr->header.free = chunk::item_count;
|
||||||
}
|
}
|
||||||
|
// Free all chunks except first_chunk.
|
||||||
|
chunk* curr = first_chunk.header.next;
|
||||||
|
while (curr) {
|
||||||
|
chunk* next = curr->header.next;
|
||||||
|
free(curr);
|
||||||
|
curr = next;
|
||||||
|
}
|
||||||
|
first_chunk.header.next = nullptr;
|
||||||
// Optionally, reset last pointer to first for reuse.
|
// Optionally, reset last pointer to first for reuse.
|
||||||
last = first;
|
last = first;
|
||||||
}
|
}
|
||||||
@@ -1656,55 +1664,60 @@ pvr_ptr_t pvrTexturePointer(Raster *r) {
|
|||||||
void im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32_t numVertices) {
|
void im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32_t numVertices) {
|
||||||
auto *verts = reinterpret_cast<Im2DVertex *>(vertices);
|
auto *verts = reinterpret_cast<Im2DVertex *>(vertices);
|
||||||
|
|
||||||
|
pvr_poly_cxt_t cxt;
|
||||||
|
|
||||||
|
if (current_raster) [[likely]] {
|
||||||
|
pvr_poly_cxt_txr(&cxt,
|
||||||
|
PVR_LIST_TR_POLY,
|
||||||
|
pvrFormatForRaster(current_raster),
|
||||||
|
current_raster->width,
|
||||||
|
current_raster->height,
|
||||||
|
pvrTexturePointer(current_raster),
|
||||||
|
PVR_FILTER_BILINEAR);
|
||||||
|
pvrTexAddress(&cxt, addressingU, addressingV);
|
||||||
|
} else {
|
||||||
|
pvr_poly_cxt_col(&cxt, PVR_LIST_TR_POLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blendEnabled) [[likely]] {
|
||||||
|
cxt.blend.src = srcBlend;
|
||||||
|
cxt.blend.dst = dstBlend;
|
||||||
|
} else {
|
||||||
|
// non blended sprites are also submitted in TR lists
|
||||||
|
// so we need to reset the blend mode
|
||||||
|
cxt.blend.src = PVR_BLEND_ONE;
|
||||||
|
cxt.blend.dst = PVR_BLEND_ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
cxt.gen.culling = cullModePvr;
|
||||||
|
cxt.depth.comparison = zFunction;
|
||||||
|
cxt.depth.write = zWrite;
|
||||||
|
|
||||||
|
cxt.gen.fog_type = fogFuncPvr;
|
||||||
|
|
||||||
|
pvr_poly_hdr_t hdr;
|
||||||
|
pvr_poly_compile(&hdr, &cxt);
|
||||||
|
|
||||||
|
assert(primType == PRIMTYPETRILIST || primType == PRIMTYPETRIFAN);
|
||||||
|
|
||||||
auto renderCB =
|
auto renderCB =
|
||||||
[=,
|
[
|
||||||
current_raster = dc::current_raster,
|
primType,
|
||||||
blend_enabled = dc::blendEnabled,
|
numVertices,
|
||||||
src_blend = dc::srcBlend,
|
cmd = hdr.cmd,
|
||||||
dst_blend = dc::dstBlend,
|
mode1 = hdr.mode1,
|
||||||
z_function = dc::zFunction,
|
mode2 = hdr.mode2,
|
||||||
z_write = dc::zWrite,
|
mode3 = hdr.mode3
|
||||||
cull_mode_pvr = dc::cullModePvr,
|
]
|
||||||
addressingU = dc::addressingU,
|
|
||||||
addressingV = dc::addressingV,
|
|
||||||
fog_func_pvr = dc::fogFuncPvr]
|
|
||||||
(const Im2DVertex* vtx) __attribute__((always_inline))
|
(const Im2DVertex* vtx) __attribute__((always_inline))
|
||||||
{
|
{
|
||||||
|
|
||||||
auto pvrHeaderSubmit = [=]() __attribute__((always_inline)) {
|
auto pvrHeaderSubmit = [=]() __attribute__((always_inline)) {
|
||||||
pvr_poly_cxt_t cxt;
|
|
||||||
|
|
||||||
if (current_raster) [[likely]] {
|
|
||||||
pvr_poly_cxt_txr(&cxt,
|
|
||||||
PVR_LIST_TR_POLY,
|
|
||||||
pvrFormatForRaster(current_raster),
|
|
||||||
current_raster->width,
|
|
||||||
current_raster->height,
|
|
||||||
pvrTexturePointer(current_raster),
|
|
||||||
PVR_FILTER_BILINEAR);
|
|
||||||
pvrTexAddress(&cxt, addressingU, addressingV);
|
|
||||||
} else {
|
|
||||||
pvr_poly_cxt_col(&cxt, PVR_LIST_TR_POLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blend_enabled) [[likely]] {
|
|
||||||
cxt.blend.src = src_blend;
|
|
||||||
cxt.blend.dst = dst_blend;
|
|
||||||
} else {
|
|
||||||
// non blended sprites are also submitted in TR lists
|
|
||||||
// so we need to reset the blend mode
|
|
||||||
cxt.blend.src = PVR_BLEND_ONE;
|
|
||||||
cxt.blend.dst = PVR_BLEND_ZERO;
|
|
||||||
}
|
|
||||||
|
|
||||||
cxt.gen.culling = cull_mode_pvr;
|
|
||||||
cxt.depth.comparison = z_function;
|
|
||||||
cxt.depth.write = z_write;
|
|
||||||
|
|
||||||
cxt.gen.fog_type = fog_func_pvr;
|
|
||||||
|
|
||||||
auto* hdr = reinterpret_cast<pvr_poly_hdr_t *>(pvr_dr_target(drState));
|
auto* hdr = reinterpret_cast<pvr_poly_hdr_t *>(pvr_dr_target(drState));
|
||||||
pvr_poly_compile(hdr, &cxt);
|
hdr->cmd = cmd;
|
||||||
|
hdr->mode1 = mode1;
|
||||||
|
hdr->mode2 = mode2;
|
||||||
|
hdr->mode3 = mode3;
|
||||||
pvr_dr_commit(hdr);
|
pvr_dr_commit(hdr);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1760,26 +1773,133 @@ void im2DRenderPrimitive(PrimitiveType primType, void *vertices, int32_t numVert
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Im2DVertex> vertData(verts, verts + numVertices);
|
Im2DVertex* vertData = (Im2DVertex*)malloc(numVertices * sizeof(Im2DVertex));
|
||||||
blendCallbacks.emplace_back([=, data = std::move(vertData)]() {
|
assert(vertData);
|
||||||
renderCB(&data[0]);
|
memcpy(vertData, verts, numVertices * sizeof(Im2DVertex));
|
||||||
|
blendCallbacks.emplace_back([renderCB, vertData]() {
|
||||||
|
renderCB(vertData);
|
||||||
|
free(vertData);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void im2DRenderIndexedPrimitive(PrimitiveType primType, void *vertices, int32 numVertices, void *indices, int32 numIndices) {
|
void im2DRenderIndexedPrimitive(PrimitiveType primType, void *vertices, int32 numVertices, void *indices, int32 numIndices) {
|
||||||
auto idx = (unsigned short*)indices;
|
auto idx = (unsigned short*)indices;
|
||||||
auto vtx = (Im2DVertex*)vertices;
|
auto verts = (Im2DVertex*)vertices;
|
||||||
|
|
||||||
std::vector<Im2DVertex> vertData(numIndices);
|
pvr_poly_cxt_t cxt;
|
||||||
|
|
||||||
for (int32 i = 0; i < numIndices; i++) {
|
if (current_raster) [[likely]] {
|
||||||
vertData[i] = vtx[idx[i]];
|
pvr_poly_cxt_txr(&cxt,
|
||||||
|
PVR_LIST_TR_POLY,
|
||||||
|
pvrFormatForRaster(current_raster),
|
||||||
|
current_raster->width,
|
||||||
|
current_raster->height,
|
||||||
|
pvrTexturePointer(current_raster),
|
||||||
|
PVR_FILTER_BILINEAR);
|
||||||
|
pvrTexAddress(&cxt, addressingU, addressingV);
|
||||||
|
} else {
|
||||||
|
pvr_poly_cxt_col(&cxt, PVR_LIST_TR_POLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
im2DRenderPrimitive(primType, &vertData[0], vertData.size());
|
if (blendEnabled) [[likely]] {
|
||||||
|
cxt.blend.src = srcBlend;
|
||||||
|
cxt.blend.dst = dstBlend;
|
||||||
|
} else {
|
||||||
|
// non blended sprites are also submitted in TR lists
|
||||||
|
// so we need to reset the blend mode
|
||||||
|
cxt.blend.src = PVR_BLEND_ONE;
|
||||||
|
cxt.blend.dst = PVR_BLEND_ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
cxt.gen.culling = cullModePvr;
|
||||||
|
cxt.depth.comparison = zFunction;
|
||||||
|
cxt.depth.write = zWrite;
|
||||||
|
|
||||||
|
cxt.gen.fog_type = fogFuncPvr;
|
||||||
|
|
||||||
|
pvr_poly_hdr_t hdr;
|
||||||
|
pvr_poly_compile(&hdr, &cxt);
|
||||||
|
|
||||||
|
assert(primType == PRIMTYPETRILIST);
|
||||||
|
|
||||||
|
auto renderCB =
|
||||||
|
[
|
||||||
|
primType,
|
||||||
|
numIndices,
|
||||||
|
cmd = hdr.cmd,
|
||||||
|
mode1 = hdr.mode1,
|
||||||
|
mode2 = hdr.mode2,
|
||||||
|
mode3 = hdr.mode3
|
||||||
|
]
|
||||||
|
(const Im2DVertex* vtx, const uint16_t* idx) __attribute__((always_inline))
|
||||||
|
{
|
||||||
|
|
||||||
|
auto pvrHeaderSubmit = [=]() __attribute__((always_inline)) {
|
||||||
|
auto* hdr = reinterpret_cast<pvr_poly_hdr_t *>(pvr_dr_target(drState));
|
||||||
|
hdr->cmd = cmd;
|
||||||
|
hdr->mode1 = mode1;
|
||||||
|
hdr->mode2 = mode2;
|
||||||
|
hdr->mode3 = mode3;
|
||||||
|
pvr_dr_commit(hdr);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto pvrVertexSubmit = [](const Im2DVertex >aVert, unsigned flags)
|
||||||
|
__attribute__((always_inline))
|
||||||
|
{
|
||||||
|
auto *pvrVert = pvr_dr_target(drState);
|
||||||
|
pvrVert->flags = flags;
|
||||||
|
pvrVert->x = gtaVert.x * VIDEO_MODE_SCALE_X;
|
||||||
|
pvrVert->y = gtaVert.y;
|
||||||
|
pvrVert->z = MATH_Fast_Invert(gtaVert.w); // this is perfect for almost every case...
|
||||||
|
pvrVert->u = gtaVert.u;
|
||||||
|
pvrVert->v = gtaVert.v;
|
||||||
|
pvrVert->argb = (gtaVert.a << 24) |
|
||||||
|
(gtaVert.r << 16) |
|
||||||
|
(gtaVert.g << 8) |
|
||||||
|
(gtaVert.b << 0);
|
||||||
|
pvr_dr_commit(pvrVert);
|
||||||
|
};
|
||||||
|
|
||||||
|
switch(primType) {
|
||||||
|
case PRIMTYPETRILIST:
|
||||||
|
pvrHeaderSubmit();
|
||||||
|
dcache_pref_block(vtx);
|
||||||
|
for(int i = 0; i < numIndices; i += 3) [[likely]] {
|
||||||
|
dcache_pref_block(&vtx[idx[i + 1]]);
|
||||||
|
pvrVertexSubmit(vtx[idx[i + 0]], PVR_CMD_VERTEX);
|
||||||
|
dcache_pref_block(&vtx[idx[i + 2]]);
|
||||||
|
pvrVertexSubmit(vtx[idx[i + 1]], PVR_CMD_VERTEX);
|
||||||
|
dcache_pref_block(&vtx[idx[i + 3]]);
|
||||||
|
pvrVertexSubmit(vtx[idx[i + 2]], PVR_CMD_VERTEX_EOL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNIMPL_LOGV("primType: %d, vertices: %p, numVertices: %d", primType, vertices, numVertices);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Im2DVertex* vertData = (Im2DVertex*)malloc(numVertices * sizeof(Im2DVertex));
|
||||||
|
assert(vertData);
|
||||||
|
memcpy(vertData, verts, numVertices * sizeof(Im2DVertex));
|
||||||
|
uint16_t* idxData = (uint16_t*)malloc(numIndices * sizeof(uint16_t));
|
||||||
|
assert(idxData);
|
||||||
|
memcpy(idxData, idx, numIndices * sizeof(uint16_t));
|
||||||
|
blendCallbacks.emplace_back([renderCB, vertData, idxData]() {
|
||||||
|
renderCB(vertData, idxData);
|
||||||
|
free(vertData);
|
||||||
|
free(idxData);
|
||||||
|
});
|
||||||
|
|
||||||
|
// std::vector<Im2DVertex> vertData(numIndices);
|
||||||
|
|
||||||
|
// for (int32 i = 0; i < numIndices; i++) {
|
||||||
|
// vertData[i] = vtx[idx[i]];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// im2DRenderPrimitive(primType, &vertData[0], vertData.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<Im3DVertex> im3dVertices;
|
static Im3DVertex* im3dVertices;
|
||||||
void im3DTransform(void *vertices, int32 numVertices, Matrix *worldMat, uint32 flags) {
|
void im3DTransform(void *vertices, int32 numVertices, Matrix *worldMat, uint32 flags) {
|
||||||
// UNIMPL_LOGV("start %d", numVertices);
|
// UNIMPL_LOGV("start %d", numVertices);
|
||||||
if(worldMat == nil){
|
if(worldMat == nil){
|
||||||
@@ -1797,7 +1917,12 @@ void im3DTransform(void *vertices, int32 numVertices, Matrix *worldMat, uint32 f
|
|||||||
rw::RawMatrix::mult(&mtx, &proj, (RawMatrix*)&DCE_MAT_SCREENVIEW);
|
rw::RawMatrix::mult(&mtx, &proj, (RawMatrix*)&DCE_MAT_SCREENVIEW);
|
||||||
// mat_load(&DCE_MAT_SCREENVIEW); // ~11 cycles.
|
// mat_load(&DCE_MAT_SCREENVIEW); // ~11 cycles.
|
||||||
mat_load(( matrix_t*)&mtx.right); // Number of cycles: ~32.
|
mat_load(( matrix_t*)&mtx.right); // Number of cycles: ~32.
|
||||||
im3dVertices.resize(numVertices);
|
if (im3dVertices) {
|
||||||
|
free(im3dVertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
im3dVertices = (Im3DVertex*)malloc(numVertices * sizeof(Im3DVertex));
|
||||||
|
assert(im3dVertices);
|
||||||
|
|
||||||
auto vtx = (Im3DVertex*)vertices;
|
auto vtx = (Im3DVertex*)vertices;
|
||||||
|
|
||||||
@@ -1825,49 +1950,56 @@ void im3DRenderIndexedPrimitive(PrimitiveType primType,
|
|||||||
void *indices,
|
void *indices,
|
||||||
int32_t numIndices)
|
int32_t numIndices)
|
||||||
{
|
{
|
||||||
|
if (primType == PRIMTYPELINELIST || primType == PRIMTYPEPOLYLINE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pvr_poly_cxt_t cxt;
|
||||||
|
|
||||||
|
if (current_raster) [[likely]] {
|
||||||
|
pvr_poly_cxt_txr(&cxt,
|
||||||
|
blendEnabled? PVR_LIST_TR_POLY : PVR_LIST_OP_POLY,
|
||||||
|
pvrFormatForRaster(current_raster),
|
||||||
|
current_raster->width,
|
||||||
|
current_raster->height,
|
||||||
|
pvrTexturePointer(current_raster),
|
||||||
|
PVR_FILTER_BILINEAR);
|
||||||
|
pvrTexAddress(&cxt, addressingU, addressingV);
|
||||||
|
} else pvr_poly_cxt_col(&cxt, blendEnabled? PVR_LIST_TR_POLY : PVR_LIST_OP_POLY);
|
||||||
|
|
||||||
|
if (blendEnabled) [[likely]] {
|
||||||
|
cxt.blend.src = srcBlend;
|
||||||
|
cxt.blend.dst = dstBlend;
|
||||||
|
}
|
||||||
|
|
||||||
|
cxt.gen.culling = cullModePvr;
|
||||||
|
cxt.depth.comparison = zFunction;
|
||||||
|
cxt.depth.write = zWrite;
|
||||||
|
|
||||||
|
|
||||||
|
cxt.gen.fog_type = fogFuncPvr;
|
||||||
|
|
||||||
|
pvr_poly_hdr_t hdr;
|
||||||
|
pvr_poly_compile(&hdr, &cxt);
|
||||||
|
|
||||||
|
assert(primType == PRIMTYPETRILIST);
|
||||||
|
|
||||||
auto renderCB =
|
auto renderCB =
|
||||||
[=,
|
[
|
||||||
current_raster = dc::current_raster,
|
numIndices,
|
||||||
cull_mode_pvr = dc::cullModePvr,
|
cmd = hdr.cmd,
|
||||||
src_blend = dc::srcBlend,
|
mode1 = hdr.mode1,
|
||||||
dst_blend = dc::dstBlend,
|
mode2 = hdr.mode2,
|
||||||
blend_enabled = dc::blendEnabled,
|
mode3 = hdr.mode3
|
||||||
z_function = dc::zFunction,
|
]
|
||||||
z_write = dc::zWrite,
|
|
||||||
addressingU = dc::addressingU,
|
|
||||||
addressingV = dc::addressingV,
|
|
||||||
fog_func_pvr = dc::fogFuncPvr]
|
|
||||||
(const void* indices, const Im3DVertex *im3dVertices) __attribute__((always_inline))
|
(const void* indices, const Im3DVertex *im3dVertices) __attribute__((always_inline))
|
||||||
|
|
||||||
{
|
{
|
||||||
auto pvrHeaderSubmit = [=]() __attribute__((always_inline)) {
|
auto pvrHeaderSubmit = [=]() __attribute__((always_inline)) {
|
||||||
pvr_poly_cxt_t cxt;
|
|
||||||
|
|
||||||
if (current_raster) [[likely]] {
|
|
||||||
pvr_poly_cxt_txr(&cxt,
|
|
||||||
blendEnabled? PVR_LIST_TR_POLY : PVR_LIST_OP_POLY,
|
|
||||||
pvrFormatForRaster(current_raster),
|
|
||||||
current_raster->width,
|
|
||||||
current_raster->height,
|
|
||||||
pvrTexturePointer(current_raster),
|
|
||||||
PVR_FILTER_BILINEAR);
|
|
||||||
pvrTexAddress(&cxt, addressingU, addressingV);
|
|
||||||
} else pvr_poly_cxt_col(&cxt, blendEnabled? PVR_LIST_TR_POLY : PVR_LIST_OP_POLY);
|
|
||||||
|
|
||||||
if (blend_enabled) [[likely]] {
|
|
||||||
cxt.blend.src = src_blend;
|
|
||||||
cxt.blend.dst = dst_blend;
|
|
||||||
}
|
|
||||||
|
|
||||||
cxt.gen.culling = cull_mode_pvr;
|
|
||||||
cxt.depth.comparison = z_function;
|
|
||||||
cxt.depth.write = z_write;
|
|
||||||
|
|
||||||
|
|
||||||
cxt.gen.fog_type = fog_func_pvr;
|
|
||||||
|
|
||||||
auto* hdr = reinterpret_cast<pvr_poly_hdr_t *>(pvr_dr_target(drState));
|
auto* hdr = reinterpret_cast<pvr_poly_hdr_t *>(pvr_dr_target(drState));
|
||||||
pvr_poly_compile(hdr, &cxt);
|
hdr->cmd = cmd;
|
||||||
|
hdr->mode1 = mode1;
|
||||||
|
hdr->mode2 = mode2;
|
||||||
|
hdr->mode3 = mode3;
|
||||||
pvr_dr_commit(hdr);
|
pvr_dr_commit(hdr);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1916,98 +2048,99 @@ void im3DRenderIndexedPrimitive(PrimitiveType primType,
|
|||||||
DCE_RenderSubmitVertex(&pvrVert, flags);
|
DCE_RenderSubmitVertex(&pvrVert, flags);
|
||||||
};
|
};
|
||||||
|
|
||||||
if(primType == PRIMTYPETRILIST) [[likely]] {
|
const auto *idx = reinterpret_cast<const uint16 *>(indices);
|
||||||
const auto *idx = reinterpret_cast<const uint16 *>(indices);
|
|
||||||
|
pvrHeaderSubmit();
|
||||||
pvrHeaderSubmit();
|
|
||||||
|
|
||||||
dcache_pref_block(idx);
|
dcache_pref_block(idx);
|
||||||
for (int32_t i = 0; i < numIndices; i += 3) [[likely]]{
|
for (int32_t i = 0; i < numIndices; i += 3) [[likely]]{
|
||||||
uint16_t idx0 = idx[i + 0];
|
uint16_t idx0 = idx[i + 0];
|
||||||
auto vtx0 = im3dVertices[idx0];
|
auto vtx0 = im3dVertices[idx0];
|
||||||
uint16_t idx1 = idx[i + 1];
|
uint16_t idx1 = idx[i + 1];
|
||||||
auto vtx1 = im3dVertices[idx1];
|
auto vtx1 = im3dVertices[idx1];
|
||||||
uint16_t idx2 = idx[i + 2];
|
uint16_t idx2 = idx[i + 2];
|
||||||
auto vtx2 = im3dVertices[idx2];
|
auto vtx2 = im3dVertices[idx2];
|
||||||
|
|
||||||
uint32_t vismask = 0;
|
uint32_t vismask = 0;
|
||||||
if(vtx0.position.z > 1.0f) vismask |= 0b100;
|
if(vtx0.position.z > 1.0f) vismask |= 0b100;
|
||||||
vismask >>= 1;
|
vismask >>= 1;
|
||||||
if(vtx1.position.z > 1.0f) vismask |= 0b100;
|
if(vtx1.position.z > 1.0f) vismask |= 0b100;
|
||||||
vismask >>= 1;
|
vismask >>= 1;
|
||||||
if(vtx2.position.z > 1.0f) vismask |= 0b100;
|
if(vtx2.position.z > 1.0f) vismask |= 0b100;
|
||||||
|
|
||||||
if (vismask == 0) continue;
|
if (vismask == 0) continue;
|
||||||
|
|
||||||
if (vismask == 7) {
|
if (vismask == 7) {
|
||||||
|
VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX);
|
||||||
|
VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX);
|
||||||
|
VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX_EOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (vismask) {
|
||||||
|
case 1: // 0 visible, 1 and 2 hidden
|
||||||
|
VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX);
|
||||||
|
pvrVertexSubmit_interp(vtx0, vtx1, PVR_CMD_VERTEX);
|
||||||
|
pvrVertexSubmit_interp(vtx0, vtx2, PVR_CMD_VERTEX_EOL);
|
||||||
|
break;
|
||||||
|
case 2: // 0 hidden, 1 visible, 2 hidden
|
||||||
|
pvrVertexSubmit_interp(vtx1, vtx0, PVR_CMD_VERTEX);
|
||||||
|
VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX);
|
||||||
|
pvrVertexSubmit_interp(vtx1, vtx2, PVR_CMD_VERTEX_EOL);
|
||||||
|
break;
|
||||||
|
case 3: // 0 and 1 visible, 2 hidden
|
||||||
VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX);
|
VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX);
|
||||||
VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX);
|
VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX);
|
||||||
|
pvrVertexSubmit_interp(vtx1, vtx2, PVR_CMD_VERTEX_EOL);
|
||||||
|
VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX);
|
||||||
|
pvrVertexSubmit_interp(vtx1, vtx2, PVR_CMD_VERTEX);
|
||||||
|
pvrVertexSubmit_interp(vtx0, vtx2, PVR_CMD_VERTEX_EOL);
|
||||||
|
break;
|
||||||
|
case 4: // 0 and 1 hidden, 2 visible
|
||||||
|
VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX);
|
||||||
|
pvrVertexSubmit_interp(vtx2, vtx0, PVR_CMD_VERTEX);
|
||||||
|
pvrVertexSubmit_interp(vtx2, vtx1, PVR_CMD_VERTEX_EOL);
|
||||||
|
break;
|
||||||
|
case 5: // 0 visible, 1 hidden, 2 visible
|
||||||
|
VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX);
|
||||||
|
pvrVertexSubmit_interp(vtx0, vtx1, PVR_CMD_VERTEX);
|
||||||
VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX_EOL);
|
VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX_EOL);
|
||||||
}
|
VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX);
|
||||||
|
pvrVertexSubmit_interp(vtx0, vtx1, PVR_CMD_VERTEX);
|
||||||
switch (vismask) {
|
pvrVertexSubmit_interp(vtx2, vtx1, PVR_CMD_VERTEX_EOL);
|
||||||
case 1: // 0 visible, 1 and 2 hidden
|
break;
|
||||||
VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX);
|
case 6: // 0 hidden, 1 and 2 visible
|
||||||
pvrVertexSubmit_interp(vtx0, vtx1, PVR_CMD_VERTEX);
|
VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX);
|
||||||
pvrVertexSubmit_interp(vtx0, vtx2, PVR_CMD_VERTEX_EOL);
|
VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX);
|
||||||
break;
|
pvrVertexSubmit_interp(vtx1, vtx0, PVR_CMD_VERTEX_EOL);
|
||||||
case 2: // 0 hidden, 1 visible, 2 hidden
|
VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX);
|
||||||
pvrVertexSubmit_interp(vtx1, vtx0, PVR_CMD_VERTEX);
|
pvrVertexSubmit_interp(vtx1, vtx0, PVR_CMD_VERTEX);
|
||||||
VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX);
|
pvrVertexSubmit_interp(vtx2, vtx0, PVR_CMD_VERTEX_EOL);
|
||||||
pvrVertexSubmit_interp(vtx1, vtx2, PVR_CMD_VERTEX_EOL);
|
break;
|
||||||
break;
|
default:
|
||||||
case 3: // 0 and 1 visible, 2 hidden
|
break;
|
||||||
VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX);
|
|
||||||
VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX);
|
|
||||||
pvrVertexSubmit_interp(vtx1, vtx2, PVR_CMD_VERTEX_EOL);
|
|
||||||
VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX);
|
|
||||||
pvrVertexSubmit_interp(vtx1, vtx2, PVR_CMD_VERTEX);
|
|
||||||
pvrVertexSubmit_interp(vtx0, vtx2, PVR_CMD_VERTEX_EOL);
|
|
||||||
break;
|
|
||||||
case 4: // 0 and 1 hidden, 2 visible
|
|
||||||
VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX);
|
|
||||||
pvrVertexSubmit_interp(vtx2, vtx0, PVR_CMD_VERTEX);
|
|
||||||
pvrVertexSubmit_interp(vtx2, vtx1, PVR_CMD_VERTEX_EOL);
|
|
||||||
break;
|
|
||||||
case 5: // 0 visible, 1 hidden, 2 visible
|
|
||||||
VTXSUBMITIM3D(vtx0, PVR_CMD_VERTEX);
|
|
||||||
pvrVertexSubmit_interp(vtx0, vtx1, PVR_CMD_VERTEX);
|
|
||||||
VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX_EOL);
|
|
||||||
VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX);
|
|
||||||
pvrVertexSubmit_interp(vtx0, vtx1, PVR_CMD_VERTEX);
|
|
||||||
pvrVertexSubmit_interp(vtx2, vtx1, PVR_CMD_VERTEX_EOL);
|
|
||||||
break;
|
|
||||||
case 6: // 0 hidden, 1 and 2 visible
|
|
||||||
VTXSUBMITIM3D(vtx1, PVR_CMD_VERTEX);
|
|
||||||
VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX);
|
|
||||||
pvrVertexSubmit_interp(vtx1, vtx0, PVR_CMD_VERTEX_EOL);
|
|
||||||
VTXSUBMITIM3D(vtx2, PVR_CMD_VERTEX);
|
|
||||||
pvrVertexSubmit_interp(vtx1, vtx0, PVR_CMD_VERTEX);
|
|
||||||
pvrVertexSubmit_interp(vtx2, vtx0, PVR_CMD_VERTEX_EOL);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else UNIMPL_LOGV("primType: %d", primType);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
assert(im3dVertices);
|
||||||
|
auto vtxData = im3dVertices;
|
||||||
|
im3dVertices = nullptr;
|
||||||
|
|
||||||
|
auto *idxData = (uint16_t*)malloc(numIndices * sizeof(uint16_t));
|
||||||
|
assert(idxData);
|
||||||
|
memcpy(idxData, indices, numIndices * sizeof(uint16_t));
|
||||||
|
|
||||||
if (blendEnabled) {
|
if (blendEnabled) {
|
||||||
auto *idx = reinterpret_cast<uint16_t *>(indices);
|
blendCallbacks.emplace_back([renderCB, idxData = idxData, vtxData = vtxData](){
|
||||||
std::vector<uint16_t> indexBuffer(idx, idx + numIndices);
|
renderCB(idxData, vtxData);
|
||||||
blendCallbacks.emplace_back([=,
|
free(idxData);
|
||||||
data = std::move(indexBuffer),
|
free(vtxData);
|
||||||
vtxData = im3dVertices](){
|
|
||||||
renderCB(&data[0], &vtxData[0]);
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
auto *idx = reinterpret_cast<uint16_t *>(indices);
|
opCallbacks.emplace_back([renderCB, idxData = idxData, vtxData = vtxData](){
|
||||||
std::vector<uint16_t> indexBuffer(idx, idx + numIndices);
|
renderCB(idxData, vtxData);
|
||||||
opCallbacks.emplace_back([=,
|
free(idxData);
|
||||||
data = std::move(indexBuffer),
|
free(vtxData);
|
||||||
vtxData = im3dVertices](){
|
|
||||||
renderCB(&data[0], &vtxData[0]);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2015,7 +2148,10 @@ void im3DRenderIndexedPrimitive(PrimitiveType primType,
|
|||||||
|
|
||||||
void im3DEnd(void) {
|
void im3DEnd(void) {
|
||||||
// UNIMPL_LOG();
|
// UNIMPL_LOG();
|
||||||
im3dVertices.resize(0);
|
if (im3dVertices) {
|
||||||
|
free(im3dVertices);
|
||||||
|
}
|
||||||
|
im3dVertices = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Vin, typename Vout>
|
template<typename Vin, typename Vout>
|
||||||
@@ -3765,12 +3901,9 @@ void defaultRenderCB(ObjPipeline *pipe, Atomic *atomic) {
|
|||||||
rw::convMatrix(&world, atomic->getFrame()->getLTM());
|
rw::convMatrix(&world, atomic->getFrame()->getLTM());
|
||||||
|
|
||||||
|
|
||||||
mat_load((matrix_t*)&cam->devView);
|
|
||||||
mat_apply((matrix_t*)&world);
|
|
||||||
mat_store((matrix_t*)&atomicContexts.back().worldView);
|
|
||||||
|
|
||||||
mat_load((matrix_t*)&cam->devProjScreen);
|
mat_load((matrix_t*)&cam->devProjScreen);
|
||||||
mat_apply((matrix_t*)&atomicContexts.back().worldView);
|
mat_apply((matrix_t*)&cam->devView);
|
||||||
|
mat_apply((matrix_t*)&world);
|
||||||
mat_store((matrix_t*)&atomicContexts.back().mtx);
|
mat_store((matrix_t*)&atomicContexts.back().mtx);
|
||||||
|
|
||||||
int16_t contextId = atomicContexts.size() - 1;
|
int16_t contextId = atomicContexts.size() - 1;
|
||||||
@@ -3907,7 +4040,6 @@ void defaultRenderCB(ObjPipeline *pipe, Atomic *atomic) {
|
|||||||
const auto& global_needsNoClip = acp->global_needsNoClip;
|
const auto& global_needsNoClip = acp->global_needsNoClip;
|
||||||
const auto& uniformObject = acp->uniform;
|
const auto& uniformObject = acp->uniform;
|
||||||
const auto& mtx = acp->mtx;
|
const auto& mtx = acp->mtx;
|
||||||
const auto& worldView = acp->worldView;
|
|
||||||
const auto& atomic = acp->atomic;
|
const auto& atomic = acp->atomic;
|
||||||
const auto& cam = acp->cam;
|
const auto& cam = acp->cam;
|
||||||
const auto meshContext = &meshContexts[acp->meshContextOffset + n];
|
const auto meshContext = &meshContexts[acp->meshContextOffset + n];
|
||||||
|
Reference in New Issue
Block a user