mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-28 10:35:43 -05:00
Added texture update batching. Added rect packing.
This commit is contained in:
parent
c3cef2bb5b
commit
435b83f1ac
8 changed files with 466 additions and 71 deletions
|
@ -11,9 +11,11 @@
|
|||
#include "../common/dbg.h"
|
||||
#include "../common/math.h"
|
||||
#include "../common/processevents.h"
|
||||
#include "../common/packrect.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <list>
|
||||
|
||||
struct PosColorVertex
|
||||
{
|
||||
|
@ -205,11 +207,7 @@ int _main_(int _argc, char** _argv)
|
|||
bgfx::destroyFragmentShader(fsh);
|
||||
|
||||
uint32_t blockSide = 0;
|
||||
uint32_t blockX = 0;
|
||||
uint32_t blockY = 0;
|
||||
const uint32_t blockWidth = 8;
|
||||
const uint32_t blockHeight = 8;
|
||||
const uint32_t textureSide = 256;
|
||||
const uint32_t textureSide = 2048;
|
||||
|
||||
bgfx::TextureHandle textureCube =
|
||||
bgfx::createTextureCube(6
|
||||
|
@ -219,15 +217,18 @@ int _main_(int _argc, char** _argv)
|
|||
, BGFX_TEXTURE_MIN_POINT|BGFX_TEXTURE_MAG_POINT|BGFX_TEXTURE_MIP_POINT
|
||||
);
|
||||
|
||||
bgfx::TextureInfo ti;
|
||||
bgfx::calcTextureSize(ti, blockWidth, blockHeight, 1, 1, bgfx::TextureFormat::BGRA8);
|
||||
|
||||
uint8_t rr = rand()%255;
|
||||
uint8_t gg = rand()%255;
|
||||
uint8_t bb = rand()%255;
|
||||
|
||||
int64_t updateTime = 0;
|
||||
|
||||
RectPackCubeT<256> cube(textureSide);
|
||||
|
||||
uint32_t hit = 0;
|
||||
uint32_t miss = 0;
|
||||
std::list<PackCube> quads;
|
||||
|
||||
while (!processEvents(width, height, debug, reset) )
|
||||
{
|
||||
// Set view 0 default viewport.
|
||||
|
@ -252,43 +253,53 @@ int _main_(int _argc, char** _argv)
|
|||
|
||||
if (now > updateTime)
|
||||
{
|
||||
// updateTime = now + freq/10;
|
||||
const bgfx::Memory* mem = bgfx::alloc(ti.storageSize);
|
||||
uint8_t* data = (uint8_t*)mem->data;
|
||||
for (uint32_t ii = 0, num = ti.storageSize*8/ti.bitsPerPixel; ii < num; ++ii)
|
||||
PackCube face;
|
||||
|
||||
uint32_t bw = bx::uint16_max(1, rand()%(textureSide/4) );
|
||||
uint32_t bh = bx::uint16_max(1, rand()%(textureSide/4) );
|
||||
|
||||
if (cube.find(bw, bh, face) )
|
||||
{
|
||||
data[0] = bb;
|
||||
data[1] = rr;
|
||||
data[2] = gg;
|
||||
data[3] = 0xff;
|
||||
data += 4;
|
||||
}
|
||||
quads.push_back(face);
|
||||
|
||||
bgfx::updateTextureCube(textureCube, blockSide, 0, blockX, blockY, blockWidth, blockHeight, mem);
|
||||
++hit;
|
||||
bgfx::TextureInfo ti;
|
||||
const Pack2D& rect = face.m_rect;
|
||||
bgfx::calcTextureSize(ti, rect.m_width, rect.m_height, 1, 1, bgfx::TextureFormat::BGRA8);
|
||||
|
||||
blockX += 8;
|
||||
if (blockX >= textureSide)
|
||||
{
|
||||
blockX = 0;
|
||||
blockY += 8;
|
||||
|
||||
if (blockY >= textureSide)
|
||||
// updateTime = now + freq/10;
|
||||
const bgfx::Memory* mem = bgfx::alloc(ti.storageSize);
|
||||
uint8_t* data = (uint8_t*)mem->data;
|
||||
for (uint32_t ii = 0, num = ti.storageSize*8/ti.bitsPerPixel; ii < num; ++ii)
|
||||
{
|
||||
rr = rand()%255;
|
||||
gg = rand()%255;
|
||||
bb = rand()%255;
|
||||
data[0] = bb;
|
||||
data[1] = rr;
|
||||
data[2] = gg;
|
||||
data[3] = 0xff;
|
||||
data += 4;
|
||||
}
|
||||
|
||||
blockY = 0;
|
||||
++blockSide;
|
||||
bgfx::updateTextureCube(textureCube, face.m_side, 0, rect.m_x, rect.m_y, rect.m_width, rect.m_height, mem);
|
||||
|
||||
if (blockSide > 5)
|
||||
{
|
||||
blockSide = 0;
|
||||
}
|
||||
rr = rand()%255;
|
||||
gg = rand()%255;
|
||||
bb = rand()%255;
|
||||
}
|
||||
else
|
||||
{
|
||||
++miss;
|
||||
|
||||
for (uint32_t ii = 0, num = bx::uint32_min(10, (uint32_t)quads.size() ); ii < num; ++ii)
|
||||
{
|
||||
const PackCube& face = quads.front();
|
||||
cube.clear(face);
|
||||
quads.pop_front();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bgfx::dbgTextPrintf(0, 4, 0x0f, "hit: %d, miss %d", hit, miss);
|
||||
|
||||
float at[3] = { 0.0f, 0.0f, 0.0f };
|
||||
float eye[3] = { 0.0f, 0.0f, -5.0f };
|
||||
|
||||
|
|
177
examples/common/packrect.h
Normal file
177
examples/common/packrect.h
Normal file
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright 2011-2013 Branimir Karadzic. All rights reserved.
|
||||
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||
*/
|
||||
|
||||
#ifndef __RECTPACK_H__
|
||||
#define __RECTPACK_H__
|
||||
|
||||
#include <bx/uint32_t.h>
|
||||
|
||||
struct Pack2D
|
||||
{
|
||||
uint16_t m_x;
|
||||
uint16_t m_y;
|
||||
uint16_t m_width;
|
||||
uint16_t m_height;
|
||||
};
|
||||
|
||||
struct PackCube
|
||||
{
|
||||
Pack2D m_rect;
|
||||
uint8_t m_side;
|
||||
};
|
||||
|
||||
template <uint16_t numBlocks>
|
||||
class RectPackCubeT;
|
||||
|
||||
template <uint16_t numBlocks>
|
||||
class RectPack2DT
|
||||
{
|
||||
public:
|
||||
RectPack2DT(uint16_t _width, uint16_t _height)
|
||||
{
|
||||
reset(_width, _height);
|
||||
}
|
||||
|
||||
void reset(uint16_t _width, uint16_t _height)
|
||||
{
|
||||
m_bw = _width/64;
|
||||
m_bh = _height/numBlocks;
|
||||
memset(m_mem, 0xff, sizeof(m_mem) );
|
||||
}
|
||||
|
||||
bool find(uint16_t _width, uint16_t _height, Pack2D& _pack)
|
||||
{
|
||||
uint16_t width = bx::uint16_min(64, (_width + m_bw - 1) / m_bw);
|
||||
uint16_t height = bx::uint16_min(numBlocks, (_height + m_bh - 1) / m_bh);
|
||||
uint16_t numx = 64-width;
|
||||
uint16_t numy = numBlocks-height;
|
||||
|
||||
const uint64_t scan = width == 64 ? UINT64_MAX : (UINT64_C(1)<<width)-1;
|
||||
|
||||
for (uint16_t starty = 0; starty <= numy; ++starty)
|
||||
{
|
||||
uint64_t mem = m_mem[starty];
|
||||
uint16_t ntz = (uint16_t)bx::uint64_cnttz(mem);
|
||||
uint64_t mask = scan<<ntz;
|
||||
|
||||
for (uint16_t xx = ntz; xx <= numx; ++xx, mask <<= 1)
|
||||
{
|
||||
uint16_t yy = starty;
|
||||
if ( (mem&mask) == mask)
|
||||
{
|
||||
uint16_t endy = starty + height;
|
||||
while (yy < endy && (m_mem[yy]&mask) == mask)
|
||||
{
|
||||
++yy;
|
||||
}
|
||||
|
||||
if (yy == endy)
|
||||
{
|
||||
uint64_t cmask = ~mask;
|
||||
for (yy = starty; yy < endy; ++yy)
|
||||
{
|
||||
m_mem[yy] &= cmask;
|
||||
}
|
||||
|
||||
_pack.m_x = xx * m_bw;
|
||||
_pack.m_y = starty * m_bh;
|
||||
_pack.m_width = width * m_bw;
|
||||
_pack.m_height = height * m_bh;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void clear(const Pack2D& _pack)
|
||||
{
|
||||
uint16_t startx = bx::uint16_min(63, _pack.m_x / m_bw);
|
||||
uint16_t starty = bx::uint16_min(numBlocks-1, _pack.m_y / m_bh);
|
||||
uint16_t endx = bx::uint16_min(64, (_pack.m_width + m_bw - 1) / m_bw + startx);
|
||||
uint16_t endy = bx::uint16_min(numBlocks, (_pack.m_height + m_bh - 1) / m_bh + starty);
|
||||
uint16_t width = endx - startx;
|
||||
|
||||
const uint64_t mask = (width == 64 ? UINT64_MAX : (UINT64_C(1)<<width)-1 )<<startx;
|
||||
|
||||
for (uint16_t yy = starty; yy < endy; ++yy)
|
||||
{
|
||||
m_mem[yy] |= mask;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
friend class RectPackCubeT<numBlocks>;
|
||||
|
||||
RectPack2DT()
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t m_mem[numBlocks];
|
||||
uint16_t m_bw;
|
||||
uint16_t m_bh;
|
||||
};
|
||||
|
||||
template <uint16_t numBlocks>
|
||||
class RectPackCubeT
|
||||
{
|
||||
public:
|
||||
RectPackCubeT(uint16_t _side)
|
||||
{
|
||||
reset(_side);
|
||||
}
|
||||
|
||||
void reset(uint16_t _side)
|
||||
{
|
||||
for (uint32_t ii = 0; ii < 6; ++ii)
|
||||
{
|
||||
m_mru[ii] = ii;
|
||||
m_ra[ii].reset(_side, _side);
|
||||
}
|
||||
}
|
||||
|
||||
bool find(uint16_t _width, uint16_t _height, PackCube& _pack)
|
||||
{
|
||||
bool found = false;
|
||||
for (uint32_t ii = 0; ii < 6; ++ii)
|
||||
{
|
||||
uint8_t side = m_mru[ii];
|
||||
found = m_ra[side].find(_width, _height, _pack.m_rect);
|
||||
|
||||
if (found)
|
||||
{
|
||||
_pack.m_side = side;
|
||||
m_mru[ii] = m_mru[0];
|
||||
m_mru[0] = side;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void clear(const PackCube& _pack)
|
||||
{
|
||||
uint8_t side = _pack.m_side;
|
||||
|
||||
uint32_t ii = 0;
|
||||
for (; ii < 6 && m_mru[ii] != side; ++ii);
|
||||
|
||||
m_mru[ii] = m_mru[0];
|
||||
m_mru[0] = side;
|
||||
|
||||
m_ra[side].clear(_pack.m_rect);
|
||||
}
|
||||
|
||||
private:
|
||||
RectPackCubeT();
|
||||
|
||||
RectPack2DT<numBlocks> m_ra[6];
|
||||
uint8_t m_mru[6];
|
||||
};
|
||||
|
||||
#endif // __RECTPACK_H__
|
155
src/bgfx_p.h
155
src/bgfx_p.h
|
@ -194,16 +194,6 @@ namespace bgfx
|
|||
const char* getAttribName(Attrib::Enum _attr);
|
||||
bool renderFrame();
|
||||
|
||||
inline uint16_t uint16_min(uint16_t _a, uint16_t _b)
|
||||
{
|
||||
return _a > _b ? _b : _a;
|
||||
}
|
||||
|
||||
inline uint16_t uint16_max(uint16_t _a, uint16_t _b)
|
||||
{
|
||||
return _a < _b ? _b : _a;
|
||||
}
|
||||
|
||||
inline uint32_t gcd(uint32_t _a, uint32_t _b)
|
||||
{
|
||||
do
|
||||
|
@ -374,6 +364,49 @@ namespace bgfx
|
|||
bool m_init;
|
||||
};
|
||||
|
||||
template <uint32_t maxKeys>
|
||||
struct UpdateBatchT
|
||||
{
|
||||
UpdateBatchT()
|
||||
: m_num(0)
|
||||
{
|
||||
}
|
||||
|
||||
void add(uint32_t _key, uint32_t _value)
|
||||
{
|
||||
uint32_t num = m_num++;
|
||||
m_keys[num] = _key;
|
||||
m_values[num] = _value;
|
||||
}
|
||||
|
||||
bool sort()
|
||||
{
|
||||
if (0 < m_num)
|
||||
{
|
||||
uint32_t* tempKeys = (uint32_t*)alloca(sizeof(m_keys) );
|
||||
uint32_t* tempValues = (uint32_t*)alloca(sizeof(m_values) );
|
||||
bx::radixSort32(m_keys, tempKeys, m_values, tempValues, m_num);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isFull() const
|
||||
{
|
||||
return m_num >= maxKeys;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_num = 0;
|
||||
}
|
||||
|
||||
uint32_t m_num;
|
||||
uint32_t m_keys[maxKeys];
|
||||
uint32_t m_values[maxKeys];
|
||||
};
|
||||
|
||||
struct ClearQuad
|
||||
{
|
||||
void init();
|
||||
|
@ -480,6 +513,12 @@ namespace bgfx
|
|||
read(reinterpret_cast<uint8_t*>(&_in), sizeof(Type) );
|
||||
}
|
||||
|
||||
void skip(uint32_t _size)
|
||||
{
|
||||
BX_CHECK(m_pos < m_size, "");
|
||||
m_pos += _size;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
m_pos = 0;
|
||||
|
@ -2369,7 +2408,9 @@ namespace bgfx
|
|||
void rendererCreateProgram(ProgramHandle _handle, VertexShaderHandle _vsh, FragmentShaderHandle _fsh);
|
||||
void rendererDestroyProgram(FragmentShaderHandle _handle);
|
||||
void rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags);
|
||||
void rendererUpdateTextureBegin(TextureHandle _handle, uint8_t _side, uint8_t _mip);
|
||||
void rendererUpdateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem);
|
||||
void rendererUpdateTextureEnd();
|
||||
void rendererDestroyTexture(TextureHandle _handle);
|
||||
void rendererCreateRenderTarget(RenderTargetHandle _handle, uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags);
|
||||
void rendererDestroyRenderTarget(RenderTargetHandle _handle);
|
||||
|
@ -2403,6 +2444,66 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
|
||||
void flushTextureUpdateBatch(CommandBuffer& _cmdbuf)
|
||||
{
|
||||
if (m_textureUpdateBatch.sort() )
|
||||
{
|
||||
const uint32_t pos = _cmdbuf.m_pos;
|
||||
|
||||
uint32_t currentKey = UINT32_MAX;
|
||||
|
||||
for (uint32_t ii = 0, num = m_textureUpdateBatch.m_num; ii < num; ++ii)
|
||||
{
|
||||
_cmdbuf.m_pos = m_textureUpdateBatch.m_values[ii];
|
||||
|
||||
TextureHandle handle;
|
||||
_cmdbuf.read(handle);
|
||||
|
||||
uint8_t side;
|
||||
_cmdbuf.read(side);
|
||||
|
||||
uint8_t mip;
|
||||
_cmdbuf.read(mip);
|
||||
|
||||
Rect rect;
|
||||
_cmdbuf.read(rect);
|
||||
|
||||
uint16_t zz;
|
||||
_cmdbuf.read(zz);
|
||||
|
||||
uint16_t depth;
|
||||
_cmdbuf.read(depth);
|
||||
|
||||
Memory* mem;
|
||||
_cmdbuf.read(mem);
|
||||
|
||||
uint32_t key = m_textureUpdateBatch.m_keys[ii];
|
||||
if (key != currentKey)
|
||||
{
|
||||
if (currentKey != UINT32_MAX)
|
||||
{
|
||||
rendererUpdateTextureEnd();
|
||||
}
|
||||
currentKey = key;
|
||||
rendererUpdateTextureBegin(handle, side, mip);
|
||||
}
|
||||
|
||||
rendererUpdateTexture(handle, side, mip, rect, zz, depth, mem);
|
||||
|
||||
release(mem);
|
||||
}
|
||||
|
||||
if (currentKey != UINT32_MAX)
|
||||
{
|
||||
rendererUpdateTextureEnd();
|
||||
}
|
||||
|
||||
m_textureUpdateBatch.reset();
|
||||
|
||||
_cmdbuf.m_pos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
void rendererExecCommands(CommandBuffer& _cmdbuf)
|
||||
{
|
||||
_cmdbuf.reset();
|
||||
|
@ -2677,6 +2778,13 @@ namespace bgfx
|
|||
|
||||
case CommandBuffer::UpdateTexture:
|
||||
{
|
||||
if (m_textureUpdateBatch.isFull() )
|
||||
{
|
||||
flushTextureUpdateBatch(_cmdbuf);
|
||||
}
|
||||
|
||||
uint32_t value = _cmdbuf.m_pos;
|
||||
|
||||
TextureHandle handle;
|
||||
_cmdbuf.read(handle);
|
||||
|
||||
|
@ -2686,21 +2794,14 @@ namespace bgfx
|
|||
uint8_t mip;
|
||||
_cmdbuf.read(mip);
|
||||
|
||||
Rect rect;
|
||||
_cmdbuf.read(rect);
|
||||
_cmdbuf.skip(sizeof(Rect)+sizeof(uint16_t)+sizeof(uint16_t)+sizeof(Memory*) );
|
||||
|
||||
uint32_t key = (handle.idx<<16)
|
||||
| (side<<8)
|
||||
| mip
|
||||
;
|
||||
|
||||
uint16_t zz;
|
||||
_cmdbuf.read(zz);
|
||||
|
||||
uint16_t depth;
|
||||
_cmdbuf.read(depth);
|
||||
|
||||
Memory* mem;
|
||||
_cmdbuf.read(mem);
|
||||
|
||||
rendererUpdateTexture(handle, side, mip, rect, zz, depth, mem);
|
||||
|
||||
release(mem);
|
||||
m_textureUpdateBatch.add(key, value);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2794,6 +2895,8 @@ namespace bgfx
|
|||
break;
|
||||
}
|
||||
} while (!end);
|
||||
|
||||
flushTextureUpdateBatch(_cmdbuf);
|
||||
}
|
||||
|
||||
void rendererSubmit();
|
||||
|
@ -2915,6 +3018,10 @@ namespace bgfx
|
|||
|
||||
bool m_rendererInitialized;
|
||||
bool m_exit;
|
||||
|
||||
BX_CACHE_LINE_ALIGN_MARKER();
|
||||
typedef UpdateBatchT<256> TextureUpdateBatch;
|
||||
TextureUpdateBatch m_textureUpdateBatch;
|
||||
};
|
||||
|
||||
} // namespace bgfx
|
||||
|
|
|
@ -1799,7 +1799,7 @@ namespace bgfx
|
|||
, ...
|
||||
);
|
||||
#else
|
||||
deviceCtx->UpdateSubresource(m_ptr, subres, &box, _mem->data, _rect.m_width*4, 0);
|
||||
deviceCtx->UpdateSubresource(m_ptr, subres, &box, _mem->data, _rect.m_width*4, 0);
|
||||
#endif // 0
|
||||
}
|
||||
|
||||
|
@ -2011,11 +2011,19 @@ namespace bgfx
|
|||
s_renderCtx.m_textures[_handle.idx].create(_mem, _flags);
|
||||
}
|
||||
|
||||
void Context::rendererUpdateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/)
|
||||
{
|
||||
}
|
||||
|
||||
void Context::rendererUpdateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
|
||||
{
|
||||
s_renderCtx.m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _mem);
|
||||
}
|
||||
|
||||
void Context::rendererUpdateTextureEnd()
|
||||
{
|
||||
}
|
||||
|
||||
void Context::rendererDestroyTexture(TextureHandle _handle)
|
||||
{
|
||||
s_renderCtx.m_textures[_handle.idx].destroy();
|
||||
|
|
|
@ -881,6 +881,12 @@ namespace bgfx
|
|||
UniformRegistry m_uniformReg;
|
||||
void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
|
||||
|
||||
Texture* m_updateTexture;
|
||||
uint8_t* m_updateTextureBits;
|
||||
uint32_t m_updateTexturePitch;
|
||||
uint8_t m_updateTextureSide;
|
||||
uint8_t m_updateTextureMip;
|
||||
|
||||
TextVideoMem m_textVideoMem;
|
||||
RenderTargetHandle m_rt;
|
||||
bool m_rtMsaa;
|
||||
|
@ -1346,6 +1352,42 @@ namespace bgfx
|
|||
BX_CHECK(false, "You should not be here.");
|
||||
}
|
||||
|
||||
void Texture::dirty(uint8_t _side, const Rect& _rect)
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case Texture2D:
|
||||
{
|
||||
RECT rect;
|
||||
rect.left = _rect.m_x;
|
||||
rect.top = _rect.m_y;
|
||||
rect.right = rect.left + _rect.m_width;
|
||||
rect.bottom = rect.top + _rect.m_height;
|
||||
DX_CHECK(m_texture2d->AddDirtyRect(&rect) );
|
||||
}
|
||||
return;
|
||||
|
||||
case Texture3D:
|
||||
{
|
||||
// DX_CHECK(m_texture3d->AddDirtyRect(_box) );
|
||||
}
|
||||
return;
|
||||
|
||||
case TextureCube:
|
||||
{
|
||||
RECT rect;
|
||||
rect.left = _rect.m_x;
|
||||
rect.top = _rect.m_y;
|
||||
rect.right = rect.left + _rect.m_width;
|
||||
rect.bottom = rect.top + _rect.m_height;
|
||||
DX_CHECK(m_textureCube->AddDirtyRect(D3DCUBEMAP_FACES(_side), &rect) );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
BX_CHECK(false, "You should not be here.");
|
||||
}
|
||||
|
||||
void Texture::create(const Memory* _mem, uint32_t _flags)
|
||||
{
|
||||
m_tau = s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT];
|
||||
|
@ -1548,22 +1590,41 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
|
||||
void Texture::updateBegin(uint8_t _side, uint8_t _mip)
|
||||
{
|
||||
uint32_t slicePitch;
|
||||
s_renderCtx.m_updateTextureSide = _side;
|
||||
s_renderCtx.m_updateTextureMip = _mip;
|
||||
s_renderCtx.m_updateTextureBits = lock(_side, _mip, s_renderCtx.m_updateTexturePitch, slicePitch);
|
||||
}
|
||||
|
||||
void Texture::update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
|
||||
{
|
||||
uint32_t pitch;
|
||||
uint32_t slicePitch;
|
||||
uint8_t* bits = lock(_side, _mip, pitch, slicePitch, &_rect);
|
||||
uint32_t bpp = s_textureFormat[m_format].m_bpp;
|
||||
uint32_t srcpitch = _rect.m_width*bpp/8;
|
||||
uint32_t dstpitch = s_renderCtx.m_updateTexturePitch;
|
||||
uint8_t* bits = s_renderCtx.m_updateTextureBits + _rect.m_y*dstpitch + _rect.m_x*bpp/8;
|
||||
|
||||
uint32_t srcpitch = _rect.m_width*s_textureFormat[m_format].m_bpp/8;
|
||||
uint32_t dstpitch = pitch;
|
||||
for (uint32_t yy = 0, height = _rect.m_height; yy < height; ++yy)
|
||||
if (srcpitch == dstpitch)
|
||||
{
|
||||
uint8_t* src = &_mem->data[yy*srcpitch];
|
||||
uint8_t* dst = &bits[yy*dstpitch];
|
||||
memcpy(dst, src, srcpitch);
|
||||
memcpy(bits, _mem->data, srcpitch*_rect.m_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t yy = 0, height = _rect.m_height; yy < height; ++yy)
|
||||
{
|
||||
uint8_t* src = &_mem->data[yy*srcpitch];
|
||||
uint8_t* dst = &bits[yy*dstpitch];
|
||||
memcpy(dst, src, srcpitch);
|
||||
}
|
||||
}
|
||||
|
||||
unlock(_side, _mip);
|
||||
dirty(_side, _rect);
|
||||
}
|
||||
|
||||
void Texture::updateEnd()
|
||||
{
|
||||
unlock(s_renderCtx.m_updateTextureSide, s_renderCtx.m_updateTextureMip);
|
||||
}
|
||||
|
||||
void Texture::commit(uint8_t _stage)
|
||||
|
@ -1990,9 +2051,21 @@ namespace bgfx
|
|||
s_renderCtx.m_textures[_handle.idx].create(_mem, _flags);
|
||||
}
|
||||
|
||||
void Context::rendererUpdateTextureBegin(TextureHandle _handle, uint8_t _side, uint8_t _mip)
|
||||
{
|
||||
s_renderCtx.m_updateTexture = &s_renderCtx.m_textures[_handle.idx];
|
||||
s_renderCtx.m_updateTexture->updateBegin(_side, _mip);
|
||||
}
|
||||
|
||||
void Context::rendererUpdateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
|
||||
{
|
||||
s_renderCtx.m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _mem);
|
||||
s_renderCtx.m_updateTexture->update(_side, _mip, _rect, _z, _depth, _mem);
|
||||
}
|
||||
|
||||
void Context::rendererUpdateTextureEnd()
|
||||
{
|
||||
s_renderCtx.m_updateTexture->updateEnd();
|
||||
s_renderCtx.m_updateTexture = NULL;
|
||||
}
|
||||
|
||||
void Context::rendererDestroyTexture(TextureHandle _handle)
|
||||
|
|
|
@ -320,6 +320,7 @@ namespace bgfx
|
|||
|
||||
uint8_t* lock(uint8_t _side, uint8_t _lod, uint32_t& _pitch, uint32_t& _slicePitch, const Rect* _rect = NULL);
|
||||
void unlock(uint8_t _side, uint8_t _lod);
|
||||
void dirty(uint8_t _side, const Rect& _rect);
|
||||
|
||||
void create(const Memory* _mem, uint32_t _flags);
|
||||
|
||||
|
@ -328,7 +329,9 @@ namespace bgfx
|
|||
DX_RELEASE(m_ptr, 0);
|
||||
}
|
||||
|
||||
void updateBegin(uint8_t _side, uint8_t _mip);
|
||||
void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem);
|
||||
void updateEnd();
|
||||
void commit(uint8_t _stage);
|
||||
|
||||
union
|
||||
|
|
|
@ -2187,11 +2187,19 @@ namespace bgfx
|
|||
s_renderCtx.m_textures[_handle.idx].create(_mem, _flags);
|
||||
}
|
||||
|
||||
void Context::rendererUpdateTextureBegin(TextureHandle _handle, uint8_t _side, uint8_t _mip)
|
||||
{
|
||||
}
|
||||
|
||||
void Context::rendererUpdateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
|
||||
{
|
||||
s_renderCtx.m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _mem);
|
||||
}
|
||||
|
||||
void Context::rendererUpdateTextureEnd()
|
||||
{
|
||||
}
|
||||
|
||||
void Context::rendererDestroyTexture(TextureHandle _handle)
|
||||
{
|
||||
s_renderCtx.m_textures[_handle.idx].destroy();
|
||||
|
|
|
@ -124,10 +124,18 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
|
||||
void Context::rendererUpdateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/)
|
||||
{
|
||||
}
|
||||
|
||||
void Context::rendererUpdateTexture(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/, const Rect& /*_rect*/, uint16_t /*_z*/, uint16_t /*_depth*/, const Memory* /*_mem*/)
|
||||
{
|
||||
}
|
||||
|
||||
void Context::rendererUpdateTextureEnd()
|
||||
{
|
||||
}
|
||||
|
||||
void Context::rendererDestroyTexture(TextureHandle /*_handle*/)
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue