Add a WIP UploadToScreen implementation. This almost displays right.

This commit is contained in:
Eric Anholt 2007-03-02 13:44:57 -08:00
parent ca0fa875e8
commit fd52d63560
3 changed files with 130 additions and 0 deletions

View File

@ -131,6 +131,43 @@ extern void I830DPRINTF_stub(const char *filename, int line,
outring &= ringmask; \
} while (0)
static inline void memset_volatile(volatile void *b, int c, size_t len)
{
int i;
for (i = 0; i < len; i++)
((volatile char *)b)[i] = c;
}
static inline void memcpy_volatile(volatile void *dst, const void *src,
size_t len)
{
int i;
for (i = 0; i < len; i++)
((volatile char *)dst)[i] = ((volatile char *)src)[i];
}
/** Copies a given number of bytes to the ring */
#define OUT_RING_COPY(n, ptr) do { \
if (I810_DEBUG & DEBUG_VERBOSE_RING) \
ErrorF("OUT_RING_DATA %d bytes\n", n); \
memcpy_volatile(virt + outring, ptr, n); \
outring += n; \
ringused += n; \
outring &= ringmask; \
} while (0)
/** Pads the ring with a given number of zero bytes */
#define OUT_RING_PAD(n) do { \
if (I810_DEBUG & DEBUG_VERBOSE_RING) \
ErrorF("OUT_RING_PAD %d bytes\n", n); \
memset_volatile(virt + outring, 0, n); \
outring += n; \
ringused += n; \
outring &= ringmask; \
} while (0)
union intfloat {
float f;
unsigned int ui;

View File

@ -1906,6 +1906,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define SRC_COPY_BLT_WRITE_ALPHA (1<<21)
#define SRC_COPY_BLT_WRITE_RGB (1<<20)
#define XY_PAT_BLT_IMMEDIATE ((2<<29)|(0x72<<22))
#define XY_MONO_PAT_BLT_CMD ((0x2<<29)|(0x52<<22)|0x7)
#define XY_MONO_PAT_VERT_SEED ((1<<10)|(1<<9)|(1<<8))
#define XY_MONO_PAT_HORT_SEED ((1<<14)|(1<<13)|(1<<12))

View File

@ -297,6 +297,93 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform,
}
}
/**
* Uploads data from system memory to the framebuffer using a series of
* 8x8 pattern blits.
*/
static Bool
i830_upload_to_screen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
int src_pitch)
{
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
const int uts_width_max = 16, uts_height_max = 16;
int cpp = pDst->drawable.bitsPerPixel / 8;
int sub_x, sub_y;
CARD32 br13;
CARD32 offset;
if (w > uts_width_max || h > uts_height_max)
I830FALLBACK("too large for upload to screen (%d,%d)", w, h);
offset = exaGetPixmapOffset(pDst);
br13 = exaGetPixmapPitch(pDst);
br13 |= ((I830PatternROP[GXcopy] & 0xff) << 16);
switch (pDst->drawable.bitsPerPixel) {
case 16:
br13 |= 1 << 24;
break;
case 32:
br13 |= 3 << 24;
break;
}
for (sub_y = 0; sub_y < uts_height_max && sub_y < h; sub_y += 8) {
int sub_height;
if (sub_y + 8 > h)
sub_height = h - sub_y;
else
sub_height = 8;
for (sub_x = 0; sub_x < uts_width_max && sub_x < w; sub_x += 8) {
int sub_width, line;
char *src_line = src + sub_y * src_pitch + sub_x * cpp;
if (sub_x + 8 > w)
sub_width = w - sub_x;
else
sub_width = 8;
BEGIN_LP_RING(6 + (cpp * 8 * 8 / 4));
/* XXX We may need a pattern offset here for {x,y} % 8 != 0*/
OUT_RING(XY_PAT_BLT_IMMEDIATE |
XY_SRC_COPY_BLT_WRITE_ALPHA |
XY_SRC_COPY_BLT_WRITE_RGB |
(3 + cpp * 8 * 8 / 4));
OUT_RING(br13);
OUT_RING(((y + sub_y) << 16) | (x + sub_x));
OUT_RING(((y + sub_y + sub_height) << 16) |
(x + sub_x + sub_width));
OUT_RING(offset);
/* Write out the lines with valid data, followed by any needed
* padding
*/
for (line = 0; line < sub_height; line++) {
OUT_RING_COPY(sub_width * cpp, src_line);
src_line += src_pitch;
if (sub_width != 8)
OUT_RING_PAD((8 - sub_width) * cpp);
}
/* Write out any full padding lines to follow */
if (sub_height != 8)
OUT_RING_PAD(8 * cpp * (8 - sub_height));
OUT_RING(MI_NOOP);
ADVANCE_LP_RING();
}
}
exaMarkSync(pDst->drawable.pScreen);
/* exaWaitSync(pDst->drawable.pScreen); */
return TRUE;
}
/*
* TODO:
* - Dual head?
@ -421,6 +508,10 @@ I830EXAInit(ScreenPtr pScreen)
pI830->EXADriverPtr->DoneComposite = i830_done_composite;
}
/* UploadToScreen/DownloadFromScreen */
if (0)
pI830->EXADriverPtr->UploadToScreen = i830_upload_to_screen;
if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"EXA initialization failed; trying older version\n");