@ -6079,13 +6079,15 @@ static void vrend_resource_copy_fallback(struct vrend_context *ctx,
const struct pipe_box * src_box )
{
char * tptr ;
uint32_t transfer_size ;
uint32_t transfer_size , src_stride , dst_stride ;
GLenum glformat , gltype ;
int elsize = util_format_get_blocksize ( dst_res - > base . format ) ;
int compressed = util_format_is_compressed ( dst_res - > base . format ) ;
int cube_slice = 1 ;
uint32_t slice_size , slice_offset ;
int i ;
struct pipe_box box ;
if ( src_res - > target = = GL_TEXTURE_CUBE_MAP )
cube_slice = 6 ;
@ -6094,6 +6096,12 @@ static void vrend_resource_copy_fallback(struct vrend_context *ctx,
return ;
}
box = * src_box ;
box . depth = vrend_get_texture_depth ( src_res , src_level ) ;
src_stride = util_format_get_stride ( src_res - > base . format , src_res - > base . width0 ) ;
dst_stride = util_format_get_stride ( dst_res - > base . format , dst_res - > base . width0 ) ;
/* this is ugly need to do a full GetTexImage */
slice_size = util_format_get_nblocks ( src_res - > base . format , u_minify ( src_res - > base . width0 , src_level ) , u_minify ( src_res - > base . height0 , src_level ) ) *
util_format_get_blocksize ( src_res - > base . format ) ;
@ -6109,43 +6117,61 @@ static void vrend_resource_copy_fallback(struct vrend_context *ctx,
if ( compressed )
glformat = tex_conv_table [ src_res - > base . format ] . internalformat ;
switch ( elsize ) {
case 1 :
glPixelStorei ( GL_PACK_ALIGNMENT , 1 ) ;
break ;
case 2 :
glPixelStorei ( GL_PACK_ALIGNMENT , 2 ) ;
break ;
case 4 :
default :
glPixelStorei ( GL_PACK_ALIGNMENT , 4 ) ;
break ;
case 8 :
glPixelStorei ( GL_PACK_ALIGNMENT , 8 ) ;
break ;
}
glBindTexture ( src_res - > target , src_res - > id ) ;
slice_offset = 0 ;
for ( i = 0 ; i < cube_slice ; i + + ) {
GLenum ctarget = src_res - > target = = GL_TEXTURE_CUBE_MAP ?
( GLenum ) ( GL_TEXTURE_CUBE_MAP_POSITIVE_X + i ) : src_res - > target ;
if ( compressed ) {
if ( vrend_state . have_arb_robustness )
glGetnCompressedTexImageARB ( ctarget , src_level , transfer_size , tptr + slice_offset ) ;
else if ( vrend_state . use_gles )
report_gles_missing_func ( ctx , " glGetCompressedTexImage " ) ;
else
glGetCompressedTexImage ( ctarget , src_level , tptr + slice_offset ) ;
} else {
if ( vrend_state . have_arb_robustness )
glGetnTexImageARB ( ctarget , src_level , glformat , gltype , transfer_size , tptr + slice_offset ) ;
else if ( vrend_state . use_gles )
report_gles_missing_func ( ctx , " glGetTexImage " ) ;
else
glGetTexImage ( ctarget , src_level , glformat , gltype , tptr + slice_offset ) ;
/* If we are on gles we need to rely on the textures backing
* iovec to have the data we need , otherwise we can use glGetTexture
*/
if ( vrend_state . use_gles ) {
read_transfer_data ( & src_res - > base , src_res - > iov , src_res - > num_iovs ,
tptr , src_stride , & box , src_level , 0 , false ) ;
/* Sync the dst iovec backing store because
* we might need it in a chain copy A - > B , B - > C */
write_transfer_data ( & dst_res - > base , dst_res - > iov , dst_res - > num_iovs , tptr ,
dst_stride , & box , src_level , 0 , false ) ;
/* we get values from the guest as 24-bit scaled integers
but we give them to the host GL and it interprets them
as 32 - bit scaled integers , so we need to scale them here */
if ( dst_res - > base . format = = ( enum pipe_format ) VIRGL_FORMAT_Z24X8_UNORM ) {
float depth_scale = 256.0 ;
vrend_scale_depth ( tptr , transfer_size , depth_scale ) ;
}
} else {
switch ( elsize ) {
case 1 :
glPixelStorei ( GL_PACK_ALIGNMENT , 1 ) ;
break ;
case 2 :
glPixelStorei ( GL_PACK_ALIGNMENT , 2 ) ;
break ;
case 4 :
default :
glPixelStorei ( GL_PACK_ALIGNMENT , 4 ) ;
break ;
case 8 :
glPixelStorei ( GL_PACK_ALIGNMENT , 8 ) ;
break ;
}
glBindTexture ( src_res - > target , src_res - > id ) ;
slice_offset = 0 ;
for ( i = 0 ; i < cube_slice ; i + + ) {
GLenum ctarget = src_res - > target = = GL_TEXTURE_CUBE_MAP ?
( GLenum ) ( GL_TEXTURE_CUBE_MAP_POSITIVE_X + i ) : src_res - > target ;
if ( compressed ) {
if ( vrend_state . have_arb_robustness )
glGetnCompressedTexImageARB ( ctarget , src_level , transfer_size , tptr + slice_offset ) ;
else if ( vrend_state . use_gles )
report_gles_missing_func ( ctx , " glGetCompressedTexImage " ) ;
else
glGetCompressedTexImage ( ctarget , src_level , tptr + slice_offset ) ;
} else {
if ( vrend_state . have_arb_robustness )
glGetnTexImageARB ( ctarget , src_level , glformat , gltype , transfer_size , tptr + slice_offset ) ;
else if ( vrend_state . use_gles )
report_gles_missing_func ( ctx , " glGetTexImage " ) ;
else
glGetTexImage ( ctarget , src_level , glformat , gltype , tptr + slice_offset ) ;
}
slice_offset + = slice_size ;
}
slice_offset + = slice_size ;
}
glPixelStorei ( GL_PACK_ALIGNMENT , 4 ) ;