diff --git a/Minecraft.Client/LevelRenderer.cpp b/Minecraft.Client/LevelRenderer.cpp index c5ba7ced..aa47dfa8 100644 --- a/Minecraft.Client/LevelRenderer.cpp +++ b/Minecraft.Client/LevelRenderer.cpp @@ -669,73 +669,97 @@ void LevelRenderer::resortChunks(int xc, int yc, int zc) int s2 = xChunks * CHUNK_XZSIZE; int s1 = s2 / 2; + std::vector xx2(xChunks); for (int x = 0; x < xChunks; x++) { int xx = x * CHUNK_XZSIZE; int xOff = (xx + s1 - xc); - if (xOff < 0) xOff -= (s2 - 1); + if (xOff < 0) + xOff -= (s2 - 1); + xOff /= s2; xx -= xOff * s2; + xx2[x] = xx; - if (xx < xMinChunk) xMinChunk = xx; - if (xx > xMaxChunk) xMaxChunk = xx; + if (xx < xMinChunk) + xMinChunk = xx; - for (int z = 0; z < zChunks; z++) - { - int zz = z * CHUNK_XZSIZE; - int zOff = (zz + s1 - zc); - if (zOff < 0) zOff -= (s2 - 1); - zOff /= s2; - zz -= zOff * s2; + if (xx > xMaxChunk) + xMaxChunk = xx; + } - if (zz < zMinChunk) zMinChunk = zz; - if (zz > zMaxChunk) zMaxChunk = zz; + std::vector zz2(zChunks); + for (int z = 0; z < zChunks; z++) + { + int zz = z * CHUNK_XZSIZE; + int zOff = (zz + s1 - zc); + if (zOff < 0) + zOff -= (s2 - 1); + zOff /= s2; + zz -= zOff * s2; + zz2[z] = zz; + + if (zz < zMinChunk) + zMinChunk = zz; + + if (zz > zMaxChunk) + zMaxChunk = zz; + } + + int y = 0; #ifdef __AVX__ //SSE4.2 - __m128i vYMin = _mm_set1_epi32(yMinChunk); - __m128i vYMax = _mm_set1_epi32(yMaxChunk); - __m128i vChunkSize = _mm_set1_epi32(CHUNK_SIZE); - __m128i vStep = _mm_set_epi32(3, 2, 1, 0); + __m128i vYMin = _mm_set1_epi32(INT_MAX); + __m128i vYMax = _mm_set1_epi32(INT_MIN); + __m128i vChunkSize = _mm_set1_epi32(CHUNK_SIZE); - for (int y = 0; y <= yChunks - 4; y += 4) - { - __m128i vCurrentY = _mm_add_epi32(_mm_set1_epi32(y), vStep); - __m128i vYY = _mm_mullo_epi32(vCurrentY, vChunkSize); + __m128i vStep = _mm_set_epi32(3, 2, 1, 0); - vYMin = _mm_min_epi32(vYMin, vYY); - vYMax = _mm_max_epi32(vYMax, vYY); + for (; y <= yChunks - 4; y += 4) + { + __m128i vCurrentY = _mm_add_epi32(_mm_set1_epi32(y), vStep); + __m128i vYY = _mm_mullo_epi32(vCurrentY, vChunkSize); - for (int i = 0; i < 4; ++i) - { - int finalYY = (y + i) * CHUNK_SIZE; - chunks[playerIndex][(z * yChunks + (y + i)) * xChunks + x].chunk->setPos(xx, finalYY, zz); - } - } + vYMin = _mm_min_epi32(vYMin, vYY); + vYMax = _mm_max_epi32(vYMax, vYY); + } - alignas(16) int resMin[4], resMax[4]; - _mm_store_si128((__m128i*)resMin, vYMin); - _mm_store_si128((__m128i*)resMax, vYMax); - for(int i = 0; i < 4; i++) - { - if (resMin[i] < yMinChunk) - yMinChunk = resMin[i]; - if (resMax[i] > yMaxChunk) - yMaxChunk = resMax[i]; - } - } + alignas(16) int resMin[4], resMax[4]; + _mm_store_si128((__m128i*)resMin, vYMin); + _mm_store_si128((__m128i*)resMax, vYMax); + + for(int i = 0; i < 4; i++) + { + if (resMin[i] < yMinChunk) + yMinChunk = resMin[i]; + + if (resMax[i] > yMaxChunk) + yMaxChunk = resMax[i]; + } #endif - for (int y = 0; y < yChunks; y++) - { - int yy = y * CHUNK_SIZE; - if (yy < yMinChunk) - yMinChunk = yy; - if (yy > yMaxChunk) - yMaxChunk = yy; + for (; y < yChunks; y++) + { + int yy = y * CHUNK_SIZE; + if (yy < yMinChunk) + yMinChunk = yy; - chunks[playerIndex][(z * yChunks + y) * xChunks + x].chunk->setPos(xx, yy, zz); - } + if (yy > yMaxChunk) + yMaxChunk = yy; + } + + for (int z = 0; z < zChunks; z++) + { + int zz = zz2[z]; + for (y = 0; y < yChunks; y++) + { + int yy = y * CHUNK_SIZE; + for (int x = 0; x < xChunks; x++) + { + int xx = xx2[x]; + chunks[playerIndex][(z * yChunks + y) * xChunks + x].chunk->setPos(xx, yy, zz); + } } } nonStackDirtyChunksAdded();