14a49301eSmrg/**************************************************************************
27ec681f3Smrg *
3af69d88dSmrg * Copyright 2003 VMware, Inc.
44a49301eSmrg * All Rights Reserved.
57ec681f3Smrg *
64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a
74a49301eSmrg * copy of this software and associated documentation files (the
84a49301eSmrg * "Software"), to deal in the Software without restriction, including
94a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish,
104a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to
114a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to
124a49301eSmrg * the following conditions:
137ec681f3Smrg *
144a49301eSmrg * The above copyright notice and this permission notice (including the
154a49301eSmrg * next paragraph) shall be included in all copies or substantial portions
164a49301eSmrg * of the Software.
177ec681f3Smrg *
184a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
194a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
204a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
224a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
234a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
244a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
257ec681f3Smrg *
264a49301eSmrg **************************************************************************/
274a49301eSmrg
284a49301eSmrg#include "i915_blit.h"
294a49301eSmrg#include "i915_batch.h"
304a49301eSmrg#include "i915_debug.h"
317ec681f3Smrg#include "i915_reg.h"
324a49301eSmrg
334a49301eSmrgvoid
347ec681f3Smrgi915_fill_blit(struct i915_context *i915, unsigned cpp, unsigned rgba_mask,
357ec681f3Smrg               unsigned short dst_pitch, struct i915_winsys_buffer *dst_buffer,
367ec681f3Smrg               unsigned dst_offset, short x, short y, short w, short h,
374a49301eSmrg               unsigned color)
384a49301eSmrg{
394a49301eSmrg   unsigned BR13, CMD;
404a49301eSmrg
417ec681f3Smrg   I915_DBG(DBG_BLIT, "%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", __FUNCTION__,
427ec681f3Smrg            dst_buffer, dst_pitch, dst_offset, x, y, w, h);
434a49301eSmrg
447ec681f3Smrg   if (!i915_winsys_validate_buffers(i915->batch, &dst_buffer, 1)) {
45af69d88dSmrg      FLUSH_BATCH(NULL, I915_FLUSH_ASYNC);
463464ebd5Sriastradh      assert(i915_winsys_validate_buffers(i915->batch, &dst_buffer, 1));
473464ebd5Sriastradh   }
484a49301eSmrg
494a49301eSmrg   switch (cpp) {
504a49301eSmrg   case 1:
514a49301eSmrg   case 2:
524a49301eSmrg   case 3:
537ec681f3Smrg      BR13 = (((int)dst_pitch) & 0xffff) | (0xF0 << 16) | (1 << 24);
544a49301eSmrg      CMD = XY_COLOR_BLT_CMD;
554a49301eSmrg      break;
564a49301eSmrg   case 4:
577ec681f3Smrg      BR13 = (((int)dst_pitch) & 0xffff) | (0xF0 << 16) | (1 << 24) | (1 << 25);
583464ebd5Sriastradh      CMD = (XY_COLOR_BLT_CMD | rgba_mask);
594a49301eSmrg      break;
604a49301eSmrg   default:
614a49301eSmrg      return;
624a49301eSmrg   }
634a49301eSmrg
643464ebd5Sriastradh   if (!BEGIN_BATCH(6)) {
65af69d88dSmrg      FLUSH_BATCH(NULL, I915_FLUSH_ASYNC);
663464ebd5Sriastradh      assert(BEGIN_BATCH(6));
674a49301eSmrg   }
684a49301eSmrg   OUT_BATCH(CMD);
694a49301eSmrg   OUT_BATCH(BR13);
704a49301eSmrg   OUT_BATCH((y << 16) | x);
714a49301eSmrg   OUT_BATCH(((y + h) << 16) | (x + w));
723464ebd5Sriastradh   OUT_RELOC_FENCED(dst_buffer, I915_USAGE_2D_TARGET, dst_offset);
734a49301eSmrg   OUT_BATCH(color);
743464ebd5Sriastradh
753464ebd5Sriastradh   i915_set_flush_dirty(i915, I915_FLUSH_CACHE);
764a49301eSmrg}
774a49301eSmrg
784a49301eSmrgvoid
797ec681f3Smrgi915_copy_blit(struct i915_context *i915, unsigned cpp,
807ec681f3Smrg               unsigned short src_pitch, struct i915_winsys_buffer *src_buffer,
817ec681f3Smrg               unsigned src_offset, unsigned short dst_pitch,
827ec681f3Smrg               struct i915_winsys_buffer *dst_buffer, unsigned dst_offset,
837ec681f3Smrg               short src_x, short src_y, short dst_x, short dst_y, short w,
847ec681f3Smrg               short h)
854a49301eSmrg{
864a49301eSmrg   unsigned CMD, BR13;
874a49301eSmrg   int dst_y2 = dst_y + h;
884a49301eSmrg   int dst_x2 = dst_x + w;
893464ebd5Sriastradh   struct i915_winsys_buffer *buffers[2] = {src_buffer, dst_buffer};
904a49301eSmrg
913464ebd5Sriastradh   I915_DBG(DBG_BLIT,
923464ebd5Sriastradh            "%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
937ec681f3Smrg            __FUNCTION__, src_buffer, src_pitch, src_offset, src_x, src_y,
943464ebd5Sriastradh            dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
953464ebd5Sriastradh
967ec681f3Smrg   if (!i915_winsys_validate_buffers(i915->batch, buffers, 2)) {
97af69d88dSmrg      FLUSH_BATCH(NULL, I915_FLUSH_ASYNC);
983464ebd5Sriastradh      assert(i915_winsys_validate_buffers(i915->batch, buffers, 2));
993464ebd5Sriastradh   }
1004a49301eSmrg
1014a49301eSmrg   switch (cpp) {
1024a49301eSmrg   case 1:
1034a49301eSmrg   case 2:
1044a49301eSmrg   case 3:
1057ec681f3Smrg      BR13 = (((int)dst_pitch) & 0xffff) | (0xCC << 16) | (1 << 24);
1064a49301eSmrg      CMD = XY_SRC_COPY_BLT_CMD;
1074a49301eSmrg      break;
1084a49301eSmrg   case 4:
1097ec681f3Smrg      BR13 = (((int)dst_pitch) & 0xffff) | (0xCC << 16) | (1 << 24) | (1 << 25);
1104a49301eSmrg      CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
1117ec681f3Smrg             XY_SRC_COPY_BLT_WRITE_RGB);
1124a49301eSmrg      break;
1134a49301eSmrg   default:
1144a49301eSmrg      return;
1154a49301eSmrg   }
1164a49301eSmrg
1174a49301eSmrg   if (dst_y2 < dst_y || dst_x2 < dst_x) {
1184a49301eSmrg      return;
1194a49301eSmrg   }
1204a49301eSmrg
1214a49301eSmrg   /* Hardware can handle negative pitches but loses the ability to do
1224a49301eSmrg    * proper overlapping blits in that case.  We don't really have a
1234a49301eSmrg    * need for either at this stage.
1244a49301eSmrg    */
1257ec681f3Smrg   assert(dst_pitch > 0 && src_pitch > 0);
1264a49301eSmrg
1273464ebd5Sriastradh   if (!BEGIN_BATCH(8)) {
128af69d88dSmrg      FLUSH_BATCH(NULL, I915_FLUSH_ASYNC);
1293464ebd5Sriastradh      assert(BEGIN_BATCH(8));
1304a49301eSmrg   }
1314a49301eSmrg   OUT_BATCH(CMD);
1324a49301eSmrg   OUT_BATCH(BR13);
1334a49301eSmrg   OUT_BATCH((dst_y << 16) | dst_x);
1344a49301eSmrg   OUT_BATCH((dst_y2 << 16) | dst_x2);
1353464ebd5Sriastradh   OUT_RELOC_FENCED(dst_buffer, I915_USAGE_2D_TARGET, dst_offset);
1364a49301eSmrg   OUT_BATCH((src_y << 16) | src_x);
1377ec681f3Smrg   OUT_BATCH(((int)src_pitch & 0xffff));
1383464ebd5Sriastradh   OUT_RELOC_FENCED(src_buffer, I915_USAGE_2D_SOURCE, src_offset);
1393464ebd5Sriastradh
1403464ebd5Sriastradh   i915_set_flush_dirty(i915, I915_FLUSH_CACHE);
1414a49301eSmrg}
142