more robust copy-to-texture

This commit is contained in:
David Rose 2008-08-11 22:19:26 +00:00
parent 91a6f3f413
commit 7e5c276403
12 changed files with 129 additions and 142 deletions

View File

@ -1007,9 +1007,13 @@ clear(Thread *current_thread) {
// Description: For all textures marked RTM_copy_texture,
// RTM_copy_ram, RTM_triggered_copy_texture, or
// RTM_triggered_copy_ram, do the necessary copies.
//
// Returns true if all copies are successful, false
// otherwise.
////////////////////////////////////////////////////////////////////
void GraphicsOutput::
bool GraphicsOutput::
copy_to_textures() {
bool okflag = true;
for (int i=0; i<count_textures(); i++) {
RenderTextureMode rtm_mode = get_rtm_mode(i);
if ((rtm_mode == RTM_none)||(rtm_mode == RTM_bind_or_copy)) {
@ -1018,7 +1022,7 @@ copy_to_textures() {
Texture *texture = get_texture(i);
PStatTimer timer(_copy_texture_pcollector);
nassertv(has_texture());
nassertr(has_texture(), false);
if ((rtm_mode == RTM_copy_texture)||
(rtm_mode == RTM_copy_ram)||
@ -1036,27 +1040,37 @@ copy_to_textures() {
buffer = _gsg->get_render_buffer(get_draw_buffer_type(),
get_fb_properties());
}
bool copied = false;
if (_cube_map_dr != (DisplayRegion *)NULL) {
if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) {
_gsg->framebuffer_copy_to_ram(texture, _cube_map_index,
_cube_map_dr, buffer);
copied =
_gsg->framebuffer_copy_to_ram(texture, _cube_map_index,
_cube_map_dr, buffer);
} else {
_gsg->framebuffer_copy_to_texture(texture, _cube_map_index,
_cube_map_dr, buffer);
copied =
_gsg->framebuffer_copy_to_texture(texture, _cube_map_index,
_cube_map_dr, buffer);
}
} else {
if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) {
_gsg->framebuffer_copy_to_ram(texture, _cube_map_index,
_default_display_region, buffer);
copied =
_gsg->framebuffer_copy_to_ram(texture, _cube_map_index,
_default_display_region, buffer);
} else {
_gsg->framebuffer_copy_to_texture(texture, _cube_map_index,
_default_display_region, buffer);
copied =
_gsg->framebuffer_copy_to_texture(texture, _cube_map_index,
_default_display_region, buffer);
}
}
if (!copied) {
okflag = false;
}
}
}
_trigger_copy = false;
return okflag;
}
////////////////////////////////////////////////////////////////////

View File

@ -214,7 +214,7 @@ public:
protected:
virtual void pixel_factor_changed();
void prepare_for_deletion();
void copy_to_textures();
bool copy_to_textures();
INLINE void begin_frame_spam(FrameMode mode);
INLINE void end_frame_spam(FrameMode mode);

View File

@ -1398,7 +1398,7 @@ end_draw_primitives() {
// If z > -1, it is the cube map index into which to
// copy.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
bool DXGraphicsStateGuardian8::
framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
const RenderBuffer &rb) {
set_read_buffer(rb);
@ -1413,23 +1413,22 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
if (tc == (TextureContext *)NULL) {
return;
return false;
}
DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc);
if (tex->get_texture_type() != Texture::TT_2d_texture) {
// For a specialty texture like a cube map, go the slow route
// through RAM for now.
framebuffer_copy_to_ram(tex, z, dr, rb);
return;
return framebuffer_copy_to_ram(tex, z, dr, rb);
}
nassertv(dtc->get_d3d_2d_texture() != NULL);
nassertr(dtc->get_d3d_2d_texture() != NULL, false);
IDirect3DSurface8 *tex_level_0;
hr = dtc->get_d3d_2d_texture()->GetSurfaceLevel(0, &tex_level_0);
if (FAILED(hr)) {
dxgsg8_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
return;
return false;
}
// If the texture is the wrong size, we need to do something about it.
@ -1438,7 +1437,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
if (FAILED(hr)) {
dxgsg8_cat.error() << "GetDesc failed in copy_texture" << D3DERRORSTRING(hr);
SAFE_RELEASE(tex_level_0);
return;
return false;
}
if ((texdesc.Width != tex->get_x_size())||(texdesc.Height != tex->get_y_size())) {
if ((orig_x != tex->get_x_size()) || (orig_y != tex->get_y_size())) {
@ -1448,18 +1447,18 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
// Oops, we can't re-create the texture for some reason.
dxgsg8_cat.error()
<< "Unable to re-create texture " << *dtc->get_texture() << endl;
return;
return false;
}
hr = dtc->get_d3d_2d_texture()->GetSurfaceLevel(0, &tex_level_0);
if (FAILED(hr)) {
dxgsg8_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
return;
return false;
}
hr = tex_level_0->GetDesc(&texdesc);
if (FAILED(hr)) {
dxgsg8_cat.error() << "GetDesc 2 failed in copy_texture" << D3DERRORSTRING(hr);
SAFE_RELEASE(tex_level_0);
return;
return false;
}
}
if ((texdesc.Width != tex->get_x_size())||(texdesc.Height != tex->get_y_size())) {
@ -1468,7 +1467,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
dxgsg8_cat.error()
<< "Unable to copy to texture, texture is wrong size: " << *dtc->get_texture() << endl;
SAFE_RELEASE(tex_level_0);
return;
return false;
}
}
@ -1477,7 +1476,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
if (FAILED(hr)) {
dxgsg8_cat.error() << "GetRenderTgt failed in copy_texture" << D3DERRORSTRING(hr);
SAFE_RELEASE(tex_level_0);
return;
return false;
}
RECT src_rect;
@ -1488,14 +1487,24 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
src_rect.bottom = yo+h;
// now copy from fb to tex
bool okflag = true;
hr = _d3d_device->CopyRects(render_target, &src_rect, 1, tex_level_0, 0);
if (FAILED(hr)) {
dxgsg8_cat.error()
<< "CopyRects failed in copy_texture" << D3DERRORSTRING(hr);
dxgsg8_cat.info()
<< "CopyRects failed in copy_texture " << D3DERRORSTRING(hr);
okflag = framebuffer_copy_to_ram(tex, z, dr, rb);
}
SAFE_RELEASE(render_target);
SAFE_RELEASE(tex_level_0);
if (!okflag) {
// The copy failed. Fall back to copying it to RAM and back.
// Terribly slow, but what are you going to do?
return framebuffer_copy_to_ram(tex, z, dr, rb);
}
return true;
}
@ -1594,7 +1603,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
return false;
}
copy_inverted = true;
// copy_inverted = true;
RELEASE(backbuffer, dxgsg8, "backbuffer", RELEASE_ONCE);

View File

@ -94,7 +94,7 @@ public:
bool force);
virtual void end_draw_primitives();
virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
virtual bool framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
const RenderBuffer &rb);
virtual bool framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
const RenderBuffer &rb);

View File

@ -2049,7 +2049,7 @@ end_draw_primitives() {
// If z > -1, it is the cube map index into which to
// copy.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian9::
bool DXGraphicsStateGuardian9::
framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
const RenderBuffer &rb) {
set_read_buffer(rb);
@ -2062,33 +2062,27 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
dr->get_region_pixels_i(xo, yo, w, h);
tex->set_size_padded(w, h);
bool use_stretch_rect;
use_stretch_rect = true;
if (use_stretch_rect) {
// must use a render target type texture for StretchRect
tex -> set_render_to_texture (true);
}
// must use a render target type texture for StretchRect
tex->set_render_to_texture(true);
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
if (tc == (TextureContext *)NULL) {
return;
return false;
}
DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc);
if (tex->get_texture_type() != Texture::TT_2d_texture) {
// For a specialty texture like a cube map, go the slow route
// through RAM for now.
framebuffer_copy_to_ram(tex, z, dr, rb);
return;
return framebuffer_copy_to_ram(tex, z, dr, rb);
}
nassertv(dtc->get_d3d_2d_texture() != NULL);
nassertr(dtc->get_d3d_2d_texture() != NULL, false);
IDirect3DSurface9 *tex_level_0;
hr = dtc->get_d3d_2d_texture()->GetSurfaceLevel(0, &tex_level_0);
if (FAILED(hr)) {
dxgsg9_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
return;
return false;
}
// If the texture is the wrong size, we need to do something about it.
@ -2097,7 +2091,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
if (FAILED(hr)) {
dxgsg9_cat.error() << "GetDesc failed in copy_texture" << D3DERRORSTRING(hr);
SAFE_RELEASE(tex_level_0);
return;
return false;
}
if ((texdesc.Width != tex->get_x_size())||(texdesc.Height != tex->get_y_size())) {
if ((orig_x != tex->get_x_size()) || (orig_y != tex->get_y_size())) {
@ -2107,18 +2101,18 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
// Oops, we can't re-create the texture for some reason.
dxgsg9_cat.error()
<< "Unable to re-create texture " << *dtc->get_texture() << endl;
return;
return false;
}
hr = dtc->get_d3d_2d_texture()->GetSurfaceLevel(0, &tex_level_0);
if (FAILED(hr)) {
dxgsg9_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
return;
return false;
}
hr = tex_level_0->GetDesc(&texdesc);
if (FAILED(hr)) {
dxgsg9_cat.error() << "GetDesc 2 failed in copy_texture" << D3DERRORSTRING(hr);
SAFE_RELEASE(tex_level_0);
return;
return false;
}
}
if ((texdesc.Width != tex->get_x_size())||(texdesc.Height != tex->get_y_size())) {
@ -2127,7 +2121,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
dxgsg9_cat.error()
<< "Unable to copy to texture, texture is wrong size: " << *dtc->get_texture() << endl;
SAFE_RELEASE(tex_level_0);
return;
return false;
}
}
@ -2143,7 +2137,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
<< "GetRenderTarget failed in framebuffer_copy_to_texture"
<< D3DERRORSTRING(hr);
SAFE_RELEASE(tex_level_0);
return;
return false;
}
RECT src_rect;
@ -2157,69 +2151,31 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
// hr = _d3d_device->CopyRects(render_target, &src_rect, 1, tex_level_0, 0);
// DX9
if (use_stretch_rect) {
D3DTEXTUREFILTERTYPE filter;
D3DTEXTUREFILTERTYPE filter;
filter = D3DTEXF_POINT;
filter = D3DTEXF_POINT;
// dxgsg9_cat.debug () << "framebuffer_copy_to_texture\n";
hr = _d3d_device->StretchRect (
render_target,
&src_rect,
tex_level_0,
&src_rect,
filter);
if (FAILED(hr)) {
dxgsg9_cat.error()
<< "StretchRect failed in framebuffer_copy_to_texture"
<< D3DERRORSTRING(hr);
return;
}
}
else {
// this is not efficient since it copies the entire render
// target to system memory and then copies the rectangle to the texture
// create a surface in system memory that is a duplicate of the render target
D3DPOOL pool;
IDirect3DSurface9 *temp_surface = NULL;
D3DSURFACE_DESC surface_description;
render_target -> GetDesc (&surface_description);
pool = D3DPOOL_SYSTEMMEM;
hr = _d3d_device->CreateOffscreenPlainSurface(
surface_description.Width,
surface_description.Height,
surface_description.Format,
pool,
&temp_surface,
NULL);
if (FAILED(hr)) {
dxgsg9_cat.error()
<< "CreateOffscreenPlainSurface failed in framebuffer_copy_to_texture"
<< D3DERRORSTRING(hr);
return;
}
// this copies the entire render target into system memory
hr = _d3d_device -> GetRenderTargetData (render_target, temp_surface);
if (FAILED(hr)) {
dxgsg9_cat.error() << "GetRenderTargetData failed" << D3DERRORSTRING(hr);
RELEASE(temp_surface, dxgsg9, "temp_surface", RELEASE_ONCE);
return;
}
// copy system memory version to texture
DXTextureContext9::d3d_surface_to_texture(src_rect, temp_surface,
false, tex, z);
RELEASE(temp_surface, dxgsg9, "temp_surface", RELEASE_ONCE);
bool okflag = true;
hr = _d3d_device->StretchRect(render_target, &src_rect,
tex_level_0, &src_rect,
filter);
if (FAILED(hr)) {
dxgsg9_cat.debug()
<< "StretchRect failed in framebuffer_copy_to_texture"
<< D3DERRORSTRING(hr);
okflag = false;
}
SAFE_RELEASE(render_target);
SAFE_RELEASE(tex_level_0);
if (!okflag) {
// The copy failed. Fall back to copying it to RAM and back.
// Terribly slow, but what are you going to do?
return framebuffer_copy_to_ram(tex, z, dr, rb);
}
return true;
}
@ -2234,7 +2190,8 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
// indicated texture.
////////////////////////////////////////////////////////////////////
bool DXGraphicsStateGuardian9::
framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb) {
framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
const RenderBuffer &rb) {
set_read_buffer(rb);
RECT rect;
@ -2291,7 +2248,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
// GetBackBuffer(). Might just be related to the swap_chain
// thing.
render_target_index = 0;
render_target_index = 0;
hr = _d3d_device->GetRenderTarget(render_target_index, &backbuffer);
if (FAILED(hr)) {
@ -2302,30 +2259,29 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
// Since we might not be able to Lock the back buffer, we will
// need to copy it to a temporary surface of the appropriate type
// first.
D3DPOOL pool;
D3DSURFACE_DESC surface_description;
D3DPOOL pool;
D3DSURFACE_DESC surface_description;
backbuffer -> GetDesc (&surface_description);
backbuffer -> GetDesc (&surface_description);
pool = D3DPOOL_SYSTEMMEM;
pool = D3DPOOL_SYSTEMMEM;
hr = _d3d_device->CreateOffscreenPlainSurface(
surface_description.Width,
surface_description.Height,
surface_description.Format,
pool,
&temp_surface,
NULL);
surface_description.Width,
surface_description.Height,
surface_description.Format,
pool,
&temp_surface,
NULL);
if (FAILED(hr)) {
dxgsg9_cat.error()
<< "CreateImageSurface failed in copy_pixel_buffer()"
<< D3DERRORSTRING(hr);
<< "CreateImageSurface failed in copy_pixel_buffer()"
<< D3DERRORSTRING(hr);
backbuffer->Release();
return false;
}
// Now we must copy from the backbuffer to our temporary surface.
// DX8 VERSION hr = _d3d_device->CopyRects(backbuffer, &rect, 1, temp_surface, NULL);
hr = _d3d_device -> GetRenderTargetData (backbuffer, temp_surface);
if (FAILED(hr)) {
@ -2335,7 +2291,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
return false;
}
copy_inverted = true;
// copy_inverted = true;
RELEASE(backbuffer, dxgsg9, "backbuffer", RELEASE_ONCE);
@ -2365,20 +2321,20 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
hr = _d3d_device->CreateOffscreenPlainSurface(w, h, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &temp_surface, NULL);
if (FAILED(hr)) {
dxgsg9_cat.error()
<< "CreateImageSurface failed in copy_pixel_buffer()"
<< D3DERRORSTRING(hr);
<< "CreateImageSurface failed in copy_pixel_buffer()"
<< D3DERRORSTRING(hr);
return false;
}
UINT swap_chain;
/* ***** DX9 swap chain ??? */
swap_chain = 0;
/* ***** DX9 swap chain ??? */
swap_chain = 0;
hr = _d3d_device->GetFrontBufferData(swap_chain,temp_surface);
if (hr == D3DERR_DEVICELOST) {
dxgsg9_cat.error()
<< "copy_pixel_buffer failed: device lost\n";
<< "copy_pixel_buffer failed: device lost\n";
temp_surface->Release();
return false;
}
@ -2394,8 +2350,9 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
return false;
}
copy_inverted = false;
DXTextureContext9::d3d_surface_to_texture(rect, temp_surface,
copy_inverted, tex, z);
copy_inverted, tex, z);
RELEASE(temp_surface, dxgsg9, "temp_surface", RELEASE_ONCE);

View File

@ -134,7 +134,7 @@ public:
bool force);
virtual void end_draw_primitives();
virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
virtual bool framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
const RenderBuffer &rb);
virtual bool framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
const RenderBuffer &rb);

View File

@ -290,6 +290,7 @@ CLP(GraphicsStateGuardian)::
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
reset() {
cerr << "begin reset\n";
free_pointers();
GraphicsStateGuardian::reset();
@ -1331,6 +1332,7 @@ reset() {
// Now that the GSG has been initialized, make it available for
// optimizations.
add_gsg(this);
cerr << "end reset()\n";
}
@ -3428,10 +3430,10 @@ make_geom_munger(const RenderState *state, Thread *current_thread) {
// If z > -1, it is the cube map index into which to
// copy.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
bool CLP(GraphicsStateGuardian)::
framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
const RenderBuffer &rb) {
nassertv(tex != NULL && dr != NULL);
nassertr(tex != NULL && dr != NULL, false);
set_read_buffer(rb._buffer_type);
int xo, yo, w, h;
@ -3447,17 +3449,17 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
// Sanity check everything.
if (z >= 0) {
if (!_supports_cube_map) {
return;
return false;
}
nassertv(z < 6);
nassertv(tex->get_texture_type() == Texture::TT_cube_map);
nassertr(z < 6, false);
nassertr(tex->get_texture_type() == Texture::TT_cube_map, false);
if ((w != tex->get_x_size()) ||
(h != tex->get_y_size()) ||
(w != h)) {
return;
return false;
}
} else {
nassertv(tex->get_texture_type() == Texture::TT_2d_texture);
nassertr(tex->get_texture_type() == Texture::TT_2d_texture, false);
}
// Match framebuffer format if necessary.
@ -3479,7 +3481,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
}
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
nassertv(tc != (TextureContext *)NULL);
nassertr(tc != (TextureContext *)NULL, false);
apply_texture(tc);
if (z >= 0) {
@ -3497,6 +3499,8 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
// Force reload of texture state, since we've just monkeyed with it.
_state_rs = 0;
_state._texture = 0;
return true;
}

View File

@ -181,7 +181,7 @@ public:
virtual void clear(DrawableRegion *region);
virtual void framebuffer_copy_to_texture
virtual bool framebuffer_copy_to_texture
(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb);
virtual bool framebuffer_copy_to_ram
(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb);

View File

@ -191,7 +191,7 @@ public:
virtual bool draw_points(const GeomPrimitivePipelineReader *reader, bool force)=0;
virtual void end_draw_primitives()=0;
virtual void framebuffer_copy_to_texture
virtual bool framebuffer_copy_to_texture
(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb)=0;
virtual bool framebuffer_copy_to_ram
(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb)=0;

View File

@ -36,6 +36,7 @@ OSMesaGraphicsStateGuardian(GraphicsPipe *pipe,
// OSMesa is never hardware-accelerated.
_is_hardware = false;
cerr << "constructed " << this << "\n";
}
////////////////////////////////////////////////////////////////////

View File

@ -1245,10 +1245,10 @@ end_draw_primitives() {
// If z > -1, it is the cube map index into which to
// copy.
////////////////////////////////////////////////////////////////////
void TinyGraphicsStateGuardian::
bool TinyGraphicsStateGuardian::
framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
const RenderBuffer &rb) {
nassertv(tex != NULL && dr != NULL);
nassertr(tex != NULL && dr != NULL, false);
int xo, yo, w, h;
dr->get_region_pixels_i(xo, yo, w, h);
@ -1256,12 +1256,12 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
tex->setup_2d_texture(w, h, Texture::T_unsigned_byte, Texture::F_rgba);
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
nassertv(tc != (TextureContext *)NULL);
nassertr(tc != (TextureContext *)NULL, false);
TinyTextureContext *gtc = DCAST(TinyTextureContext, tc);
GLTexture *gltex = &gtc->_gltex;
if (!setup_gltex(gltex, tex->get_x_size(), tex->get_y_size(), 1)) {
return;
return false;
}
PIXEL *ip = gltex->levels[0].pixmap + gltex->xsize * gltex->ysize;
@ -1275,6 +1275,8 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
gtc->update_data_size_bytes(gltex->xsize * gltex->ysize * 4);
gtc->mark_loaded();
gtc->enqueue_lru(&_textures_lru);
return true;
}

View File

@ -76,7 +76,7 @@ public:
bool force);
virtual void end_draw_primitives();
virtual void framebuffer_copy_to_texture
virtual bool framebuffer_copy_to_texture
(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb);
virtual bool framebuffer_copy_to_ram
(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb);