Add a WIP UploadToScreen implementation. This almost displays right.
This commit is contained in:
parent
ca0fa875e8
commit
fd52d63560
37
src/common.h
37
src/common.h
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Reference in New Issue