intel-2D: sna gen2-gen7 vsync

git-svn-id: svn://kolibrios.org@4375 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2013-12-18 12:27:38 +00:00
parent 4a209e9d17
commit 3f96e2dfdf

View File

@ -43,6 +43,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "compiler.h"
#include "sna.h"
#include "sna_reg.h"
#include <pixlib2.h>
#include <kos32sys.h>
@ -421,6 +422,139 @@ typedef struct
#define MI_LOAD_REGISTER_IMM (0x22<<23)
#define MI_WAIT_FOR_EVENT (0x03<<23)
static bool sna_emit_wait_for_scanline_hsw(struct sna *sna,
rect_t *crtc,
int pipe, int y1, int y2,
bool full_height)
{
uint32_t event;
uint32_t *b;
if (!sna->kgem.has_secure_batches)
return false;
b = kgem_get_batch(&sna->kgem);
sna->kgem.nbatch += 17;
switch (pipe) {
default: assert(0);
case 0: event = 1 << 0; break;
case 1: event = 1 << 8; break;
case 2: event = 1 << 14; break;
}
b[0] = MI_LOAD_REGISTER_IMM | 1;
b[1] = 0x44050; /* DERRMR */
b[2] = ~event;
b[3] = MI_LOAD_REGISTER_IMM | 1;
b[4] = 0xa188; /* FORCEWAKE_MT */
b[5] = 2 << 16 | 2;
/* The documentation says that the LOAD_SCAN_LINES command
* always comes in pairs. Don't ask me why. */
switch (pipe) {
default: assert(0);
case 0: event = 0 << 19; break;
case 1: event = 1 << 19; break;
case 2: event = 4 << 19; break;
}
b[8] = b[6] = MI_LOAD_SCAN_LINES_INCL | event;
b[9] = b[7] = (y1 << 16) | (y2-1);
switch (pipe) {
default: assert(0);
case 0: event = 1 << 0; break;
case 1: event = 1 << 8; break;
case 2: event = 1 << 14; break;
}
b[10] = MI_WAIT_FOR_EVENT | event;
b[11] = MI_LOAD_REGISTER_IMM | 1;
b[12] = 0xa188; /* FORCEWAKE_MT */
b[13] = 2 << 16;
b[14] = MI_LOAD_REGISTER_IMM | 1;
b[15] = 0x44050; /* DERRMR */
b[16] = ~0;
sna->kgem.batch_flags |= I915_EXEC_SECURE;
return true;
}
static bool sna_emit_wait_for_scanline_ivb(struct sna *sna,
rect_t *crtc,
int pipe, int y1, int y2,
bool full_height)
{
uint32_t *b;
uint32_t event;
uint32_t forcewake;
if (!sna->kgem.has_secure_batches)
return false;
assert(y1 >= 0);
assert(y2 > y1);
assert(sna->kgem.mode);
/* Always program one less than the desired value */
if (--y1 < 0)
y1 = crtc->b;
y2--;
switch (pipe) {
default:
assert(0);
case 0:
event = 1 << (full_height ? 3 : 0);
break;
case 1:
event = 1 << (full_height ? 11 : 8);
break;
case 2:
event = 1 << (full_height ? 21 : 14);
break;
}
if (sna->kgem.gen == 071)
forcewake = 0x1300b0; /* FORCEWAKE_VLV */
else
forcewake = 0xa188; /* FORCEWAKE_MT */
b = kgem_get_batch(&sna->kgem);
/* Both the LRI and WAIT_FOR_EVENT must be in the same cacheline */
if (((sna->kgem.nbatch + 6) >> 4) != (sna->kgem.nbatch + 10) >> 4) {
int dw = sna->kgem.nbatch + 6;
dw = ALIGN(dw, 16) - dw;
while (dw--)
*b++ = MI_NOOP;
}
b[0] = MI_LOAD_REGISTER_IMM | 1;
b[1] = 0x44050; /* DERRMR */
b[2] = ~event;
b[3] = MI_LOAD_REGISTER_IMM | 1;
b[4] = forcewake;
b[5] = 2 << 16 | 2;
b[6] = MI_LOAD_REGISTER_IMM | 1;
b[7] = 0x70068 + 0x1000 * pipe;
b[8] = (1 << 31) | (1 << 30) | (y1 << 16) | y2;
b[9] = MI_WAIT_FOR_EVENT | event;
b[10] = MI_LOAD_REGISTER_IMM | 1;
b[11] = forcewake;
b[12] = 2 << 16;
b[13] = MI_LOAD_REGISTER_IMM | 1;
b[14] = 0x44050; /* DERRMR */
b[15] = ~0;
sna->kgem.nbatch = b - sna->kgem.batch + 16;
sna->kgem.batch_flags |= I915_EXEC_SECURE;
return true;
}
static bool sna_emit_wait_for_scanline_gen6(struct sna *sna,
rect_t *crtc,
int pipe, int y1, int y2,
@ -468,6 +602,65 @@ static bool sna_emit_wait_for_scanline_gen6(struct sna *sna,
return true;
}
static bool sna_emit_wait_for_scanline_gen4(struct sna *sna,
rect_t *crtc,
int pipe, int y1, int y2,
bool full_height)
{
uint32_t event;
uint32_t *b;
if (pipe == 0) {
if (full_height)
event = MI_WAIT_FOR_PIPEA_SVBLANK;
else
event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
} else {
if (full_height)
event = MI_WAIT_FOR_PIPEB_SVBLANK;
else
event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
}
b = kgem_get_batch(&sna->kgem);
sna->kgem.nbatch += 5;
/* The documentation says that the LOAD_SCAN_LINES command
* always comes in pairs. Don't ask me why. */
b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | pipe << 20;
b[3] = b[1] = (y1 << 16) | (y2-1);
b[4] = MI_WAIT_FOR_EVENT | event;
return true;
}
static bool sna_emit_wait_for_scanline_gen2(struct sna *sna,
rect_t *crtc,
int pipe, int y1, int y2,
bool full_height)
{
uint32_t *b;
/*
* Pre-965 doesn't have SVBLANK, so we need a bit
* of extra time for the blitter to start up and
* do its job for a full height blit
*/
if (full_height)
y2 -= 2;
b = kgem_get_batch(&sna->kgem);
sna->kgem.nbatch += 5;
/* The documentation says that the LOAD_SCAN_LINES command
* always comes in pairs. Don't ask me why. */
b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | pipe << 20;
b[3] = b[1] = (y1 << 16) | (y2-1);
b[4] = MI_WAIT_FOR_EVENT | 1 << (1 + 4*pipe);
return true;
}
bool
sna_wait_for_scanline(struct sna *sna,
rect_t *crtc,
@ -504,14 +697,16 @@ sna_wait_for_scanline(struct sna *sna,
if (sna->kgem.gen >= 0100)
ret = false;
// else if (sna->kgem.gen >= 075)
// ret = sna_emit_wait_for_scanline_hsw(sna, crtc, pipe, y1, y2, full_height);
// else if (sna->kgem.gen >= 070)
// ret = sna_emit_wait_for_scanline_ivb(sna, crtc, pipe, y1, y2, full_height);
else if (sna->kgem.gen >= 075)
ret = sna_emit_wait_for_scanline_hsw(sna, crtc, pipe, y1, y2, full_height);
else if (sna->kgem.gen >= 070)
ret = sna_emit_wait_for_scanline_ivb(sna, crtc, pipe, y1, y2, full_height);
else if (sna->kgem.gen >= 060)
ret =sna_emit_wait_for_scanline_gen6(sna, crtc, pipe, y1, y2, full_height);
// else if (sna->kgem.gen >= 040)
// ret = sna_emit_wait_for_scanline_gen4(sna, crtc, pipe, y1, y2, full_height);
else if (sna->kgem.gen >= 040)
ret = sna_emit_wait_for_scanline_gen4(sna, crtc, pipe, y1, y2, full_height);
else
ret = sna_emit_wait_for_scanline_gen2(sna, crtc, pipe, y1, y2, full_height);
return ret;
}
@ -970,7 +1165,7 @@ int sna_blit_tex(bitmap_t *bitmap, bool scale, int dst_x, int dst_y,
__lock_acquire_recursive(__sna_lock);
#if 1
#if 0
{
rect_t crtc, clip;