*
**********************************************************/
-#include "svga_resource_texture.h"
#include "svga_context.h"
#include "svga_debug.h"
#include "svga_cmd.h"
+#include "svga_format.h"
+#include "svga_resource_buffer.h"
+#include "svga_resource_texture.h"
#include "svga_surface.h"
//#include "util/u_blit_sw.h"
uint32 srcSubResource, dstSubResource;
struct svga_texture *dtex, *stex;
SVGA3dCopyBox box;
- int i, num_layers = 1;
stex = svga_texture(src_tex);
dtex = svga_texture(dst_tex);
box.srcy = src_y;
box.srcz = src_z;
- if (src_tex->target == PIPE_TEXTURE_1D_ARRAY ||
- src_tex->target == PIPE_TEXTURE_2D_ARRAY) {
- /* copy layer by layer */
- box.z = 0;
- box.d = 1;
- box.srcz = 0;
-
- num_layers = depth;
- src_face = src_z;
- dst_face = dst_z;
- }
-
- /* loop over array layers */
- for (i = 0; i < num_layers; i++) {
- srcSubResource = (src_face + i) * (src_tex->last_level + 1) + src_level;
- dstSubResource = (dst_face + i) * (dst_tex->last_level + 1) + dst_level;
+ srcSubResource = src_face * (src_tex->last_level + 1) + src_level;
+ dstSubResource = dst_face * (dst_tex->last_level + 1) + dst_level;
+ ret = SVGA3D_vgpu10_PredCopyRegion(svga->swc,
+ dtex->handle, dstSubResource,
+ stex->handle, srcSubResource, &box);
+ if (ret != PIPE_OK) {
+ svga_context_flush(svga, NULL);
ret = SVGA3D_vgpu10_PredCopyRegion(svga->swc,
dtex->handle, dstSubResource,
stex->handle, srcSubResource, &box);
- if (ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_vgpu10_PredCopyRegion(svga->swc,
- dtex->handle, dstSubResource,
- stex->handle, srcSubResource, &box);
- assert(ret == PIPE_OK);
- }
+ assert(ret == PIPE_OK);
+ }
+
+ svga_define_texture_level(dtex, dst_face, dst_level);
+}
- svga_define_texture_level(dtex, dst_face + i, dst_level);
+
+/**
+ * For some texture types, we need to move the z (slice) coordinate
+ * to the layer value. For example, to select the z=3 slice of a 2D ARRAY
+ * texture, we need to use layer=3 and set z=0.
+ */
+static void
+adjust_z_layer(enum pipe_texture_target target,
+ int z_in, unsigned *layer_out, unsigned *z_out)
+{
+ if (target == PIPE_TEXTURE_CUBE ||
+ target == PIPE_TEXTURE_2D_ARRAY ||
+ target == PIPE_TEXTURE_1D_ARRAY) {
+ *layer_out = z_in;
+ *z_out = 0;
+ }
+ else {
+ *layer_out = 0;
+ *z_out = z_in;
}
}
*/
svga_surfaces_flush( svga );
- /* Fallback for buffers. */
if (dst_tex->target == PIPE_BUFFER && src_tex->target == PIPE_BUFFER) {
- util_resource_copy_region(pipe, dst_tex, dst_level, dstx, dsty, dstz,
- src_tex, src_level, src_box);
+ /* can't copy within the same buffer, unfortunately */
+ if (svga_have_vgpu10(svga) && src_tex != dst_tex) {
+ enum pipe_error ret;
+ struct svga_winsys_surface *src_surf;
+ struct svga_winsys_surface *dst_surf;
+ struct svga_buffer *dbuffer = svga_buffer(dst_tex);
+
+ src_surf = svga_buffer_handle(svga, src_tex);
+ dst_surf = svga_buffer_handle(svga, dst_tex);
+
+ ret = SVGA3D_vgpu10_BufferCopy(svga->swc, src_surf, dst_surf,
+ src_box->x, dstx, src_box->width);
+ if (ret != PIPE_OK) {
+ svga_context_flush(svga, NULL);
+ ret = SVGA3D_vgpu10_BufferCopy(svga->swc, src_surf, dst_surf,
+ src_box->x, dstx, src_box->width);
+ assert(ret == PIPE_OK);
+ }
+
+ dbuffer->dirty = TRUE;
+ }
+ else {
+ /* use map/memcpy fallback */
+ util_resource_copy_region(pipe, dst_tex, dst_level, dstx,
+ dsty, dstz, src_tex, src_level, src_box);
+ }
return;
}
stex = svga_texture(src_tex);
dtex = svga_texture(dst_tex);
- if (src_tex->target == PIPE_TEXTURE_CUBE ||
- src_tex->target == PIPE_TEXTURE_1D_ARRAY) {
- src_face_layer = src_box->z;
- src_z = 0;
- assert(src_box->depth == 1);
- }
- else {
- src_face_layer = 0;
- src_z = src_box->z;
- }
-
- if (dst_tex->target == PIPE_TEXTURE_CUBE ||
- dst_tex->target == PIPE_TEXTURE_1D_ARRAY) {
- dst_face_layer = dstz;
- dst_z = 0;
- assert(src_box->depth == 1);
- }
- else {
- dst_face_layer = 0;
- dst_z = dstz;
- }
-
- stex = svga_texture(src_tex);
- dtex = svga_texture(dst_tex);
+ adjust_z_layer(src_tex->target, src_box->z, &src_face_layer, &src_z);
+ adjust_z_layer(dst_tex->target, dstz, &dst_face_layer, &dst_z);
if (svga_have_vgpu10(svga)) {
/* vgpu10 */
if (util_format_is_compressed(src_tex->format) ==
util_format_is_compressed(dst_tex->format) &&
- !util_format_is_depth_and_stencil(src_tex->format) &&
stex->handle != dtex->handle &&
- src_tex->target == dst_tex->target) {
+ svga_resource_type(src_tex->target) ==
+ svga_resource_type(dst_tex->target)) {
copy_region_vgpu10(svga,
src_tex,
src_box->x, src_box->y, src_z,
}
+/**
+ * Are the given pipe formats compatible, in terms of vgpu10's
+ * PredCopyRegion() command?
+ */
+static bool
+formats_compatible(const struct svga_screen *ss,
+ enum pipe_format src_fmt,
+ enum pipe_format dst_fmt)
+{
+ SVGA3dSurfaceFormat src_svga_fmt, dst_svga_fmt;
+
+ src_svga_fmt = svga_translate_format(ss, src_fmt, PIPE_BIND_SAMPLER_VIEW);
+ dst_svga_fmt = svga_translate_format(ss, dst_fmt, PIPE_BIND_SAMPLER_VIEW);
+
+ src_svga_fmt = svga_typeless_format(src_svga_fmt);
+ dst_svga_fmt = svga_typeless_format(dst_svga_fmt);
+
+ return src_svga_fmt == dst_svga_fmt;
+}
+
+
/**
* The state tracker implements some resource copies with blits (for
* GL_ARB_copy_image). This function checks if we should really do the blit
return false;
stex = svga_texture(blit_info->src.resource);
- dtex = svga_texture(blit_info->src.resource);
+ dtex = svga_texture(blit_info->dst.resource);
// can't copy within one resource
if (stex->handle == dtex->handle)
return false;
- // can't copy between different resource types
- if (blit_info->src.resource->target != blit_info->dst.resource->target)
+ /* can't copy between different resource types */
+ if (svga_resource_type(blit_info->src.resource->target) !=
+ svga_resource_type(blit_info->dst.resource->target))
return false;
- // check that the blit src/dst regions are same size, no flipping, etc.
+ /* check that the blit src/dst regions are same size, no flipping, etc. */
if (blit_info->src.box.width != blit_info->dst.box.width ||
blit_info->src.box.height != blit_info->dst.box.height)
return false;
- // depth/stencil copies not supported at this time
- if (blit_info->mask != PIPE_MASK_RGBA)
- return false;
+ /* For depth+stencil formats, copy with maks != PIPE_MASK_ZS is not
+ * supported */
+ if (util_format_is_depth_and_stencil(blit_info->src.format) &&
+ blit_info->mask != (PIPE_MASK_ZS))
+ return false;
- if (blit_info->alpha_blend || blit_info->render_condition_enable ||
+ if (blit_info->alpha_blend ||
+ (svga->render_condition && blit_info->render_condition_enable) ||
blit_info->scissor_enable)
return false;
- // check that src/dst surface formats are compatible for the VGPU device.
- return util_is_format_compatible(
- util_format_description(blit_info->src.resource->format),
- util_format_description(blit_info->dst.resource->format));
+ return formats_compatible(svga_screen(svga->pipe.screen),
+ blit_info->src.resource->format,
+ blit_info->dst.resource->format);
}
const struct pipe_blit_info *blit_info)
{
struct svga_context *svga = svga_context(pipe);
+ struct pipe_blit_info blit = *blit_info;
if (!svga_have_vgpu10(svga) &&
- blit_info->src.resource->nr_samples > 1 &&
- blit_info->dst.resource->nr_samples <= 1 &&
- !util_format_is_depth_or_stencil(blit_info->src.resource->format) &&
- !util_format_is_pure_integer(blit_info->src.resource->format)) {
+ blit.src.resource->nr_samples > 1 &&
+ blit.dst.resource->nr_samples <= 1 &&
+ !util_format_is_depth_or_stencil(blit.src.resource->format) &&
+ !util_format_is_pure_integer(blit.src.resource->format)) {
debug_printf("svga: color resolve unimplemented\n");
return;
}
if (can_blit_via_copy_region_vgpu10(svga, blit_info)) {
unsigned src_face, src_z, dst_face, dst_z;
- if (blit_info->src.resource->target == PIPE_TEXTURE_CUBE) {
- src_face = blit_info->src.box.z;
- src_z = 0;
- assert(blit_info->src.box.depth == 1);
- }
- else {
- src_face = 0;
- src_z = blit_info->src.box.z;
- }
+ adjust_z_layer(blit.src.resource->target, blit.src.box.z,
+ &src_face, &src_z);
- if (blit_info->dst.resource->target == PIPE_TEXTURE_CUBE) {
- dst_face = blit_info->dst.box.z;
- dst_z = 0;
- assert(blit_info->src.box.depth == 1);
- }
- else {
- dst_face = 0;
- dst_z = blit_info->dst.box.z;
- }
+ adjust_z_layer(blit.dst.resource->target, blit.dst.box.z,
+ &dst_face, &dst_z);
copy_region_vgpu10(svga,
- blit_info->src.resource,
- blit_info->src.box.x, blit_info->src.box.y, src_z,
- blit_info->src.level, src_face,
- blit_info->dst.resource,
- blit_info->dst.box.x, blit_info->dst.box.y, dst_z,
- blit_info->dst.level, dst_face,
- blit_info->src.box.width, blit_info->src.box.height,
- blit_info->src.box.depth);
+ blit.src.resource,
+ blit.src.box.x, blit.src.box.y, src_z,
+ blit.src.level, src_face,
+ blit.dst.resource,
+ blit.dst.box.x, blit.dst.box.y, dst_z,
+ blit.dst.level, dst_face,
+ blit.src.box.width, blit.src.box.height,
+ blit.src.box.depth);
return;
}
- if (util_try_blit_via_copy_region(pipe, blit_info)) {
+ if (util_can_blit_via_copy_region(blit_info, TRUE) ||
+ util_can_blit_via_copy_region(blit_info, FALSE)) {
+ util_resource_copy_region(pipe, blit.dst.resource,
+ blit.dst.level,
+ blit.dst.box.x, blit.dst.box.y,
+ blit.dst.box.z, blit.src.resource,
+ blit.src.level, &blit.src.box);
return; /* done */
}
- if ((blit_info->mask & PIPE_MASK_S) ||
+ if ((blit.mask & PIPE_MASK_S) ||
!util_blitter_is_blit_supported(svga->blitter, blit_info)) {
debug_printf("svga: blit unsupported %s -> %s\n",
- util_format_short_name(blit_info->src.resource->format),
- util_format_short_name(blit_info->dst.resource->format));
+ util_format_short_name(blit.src.resource->format),
+ util_format_short_name(blit.dst.resource->format));
return;
}
svga->curr.sampler_views[PIPE_SHADER_FRAGMENT]);
/*util_blitter_save_render_condition(svga->blitter, svga->render_cond_query,
svga->render_cond_cond, svga->render_cond_mode);*/
- util_blitter_blit(svga->blitter, blit_info);
+ util_blitter_blit(svga->blitter, &blit);
}