forked from KolibriOS/kolibrios
intel-2D: sna gen2-gen7 vsync
git-svn-id: svn://kolibrios.org@4375 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
4a209e9d17
commit
3f96e2dfdf
@ -43,6 +43,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||||||
|
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "sna.h"
|
#include "sna.h"
|
||||||
|
#include "sna_reg.h"
|
||||||
|
|
||||||
#include <pixlib2.h>
|
#include <pixlib2.h>
|
||||||
#include <kos32sys.h>
|
#include <kos32sys.h>
|
||||||
@ -421,6 +422,139 @@ typedef struct
|
|||||||
#define MI_LOAD_REGISTER_IMM (0x22<<23)
|
#define MI_LOAD_REGISTER_IMM (0x22<<23)
|
||||||
#define MI_WAIT_FOR_EVENT (0x03<<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,
|
static bool sna_emit_wait_for_scanline_gen6(struct sna *sna,
|
||||||
rect_t *crtc,
|
rect_t *crtc,
|
||||||
int pipe, int y1, int y2,
|
int pipe, int y1, int y2,
|
||||||
@ -468,6 +602,65 @@ static bool sna_emit_wait_for_scanline_gen6(struct sna *sna,
|
|||||||
return true;
|
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
|
bool
|
||||||
sna_wait_for_scanline(struct sna *sna,
|
sna_wait_for_scanline(struct sna *sna,
|
||||||
rect_t *crtc,
|
rect_t *crtc,
|
||||||
@ -504,14 +697,16 @@ sna_wait_for_scanline(struct sna *sna,
|
|||||||
|
|
||||||
if (sna->kgem.gen >= 0100)
|
if (sna->kgem.gen >= 0100)
|
||||||
ret = false;
|
ret = false;
|
||||||
// else if (sna->kgem.gen >= 075)
|
else if (sna->kgem.gen >= 075)
|
||||||
// ret = sna_emit_wait_for_scanline_hsw(sna, crtc, pipe, y1, y2, full_height);
|
ret = sna_emit_wait_for_scanline_hsw(sna, crtc, pipe, y1, y2, full_height);
|
||||||
// else if (sna->kgem.gen >= 070)
|
else if (sna->kgem.gen >= 070)
|
||||||
// ret = sna_emit_wait_for_scanline_ivb(sna, crtc, pipe, y1, y2, full_height);
|
ret = sna_emit_wait_for_scanline_ivb(sna, crtc, pipe, y1, y2, full_height);
|
||||||
else if (sna->kgem.gen >= 060)
|
else if (sna->kgem.gen >= 060)
|
||||||
ret =sna_emit_wait_for_scanline_gen6(sna, crtc, pipe, y1, y2, full_height);
|
ret =sna_emit_wait_for_scanline_gen6(sna, crtc, pipe, y1, y2, full_height);
|
||||||
// else if (sna->kgem.gen >= 040)
|
else if (sna->kgem.gen >= 040)
|
||||||
// ret = sna_emit_wait_for_scanline_gen4(sna, crtc, pipe, y1, y2, full_height);
|
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;
|
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);
|
__lock_acquire_recursive(__sna_lock);
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
{
|
{
|
||||||
rect_t crtc, clip;
|
rect_t crtc, clip;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user