Enabling overlay requires a command ring buffer, and we're setting one (very
small) up for this specific task - this will later be used for the acceleration engine as well. Some more work on overlay initialization, doesn't do anything yet, though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17254 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
#define INTEL_EXTREME_H
|
||||
|
||||
|
||||
#include "lock.h"
|
||||
|
||||
#include <memory_manager.h>
|
||||
|
||||
#include <Accelerant.h>
|
||||
@@ -38,6 +40,16 @@ struct pll_info {
|
||||
uint32 divisor_register;
|
||||
};
|
||||
|
||||
struct ring_buffer {
|
||||
struct lock lock;
|
||||
uint32 register_base;
|
||||
uint32 handle;
|
||||
uint32 offset;
|
||||
uint32 size;
|
||||
uint32 position;
|
||||
uint8 *base;
|
||||
};
|
||||
|
||||
struct overlay_registers;
|
||||
|
||||
struct intel_shared_info {
|
||||
@@ -57,6 +69,8 @@ struct intel_shared_info {
|
||||
|
||||
uint32 frame_buffer_offset;
|
||||
|
||||
ring_buffer primary_ring_buffer;
|
||||
|
||||
int32 overlay_channel_used;
|
||||
uint32 overlay_token;
|
||||
uint8* physical_overlay_registers;
|
||||
@@ -124,6 +138,21 @@ struct intel_free_graphics_memory {
|
||||
//----------------------------------------------------------
|
||||
// Register definitions, taken from X driver
|
||||
|
||||
#define INTEL_PAGE_TABLE_CONTROL 0x02020
|
||||
#define INTEL_PAGE_TABLE_ERROR 0x02024
|
||||
#define INTEL_HARDWARE_STATUS_PAGE 0x02080
|
||||
|
||||
#define INTEL_PRIMARY_RING_BUFFER 0x02030
|
||||
#define INTEL_SECONDARY_RING_BUFFER_0 0x02100
|
||||
#define INTEL_SECONDARY_RING_BUFFER_1 0x02110
|
||||
// offsets for the ring buffer base registers above
|
||||
#define RING_BUFFER_TAIL 0x0
|
||||
#define RING_BUFFER_HEAD 0x4
|
||||
#define RING_BUFFER_START 0x8
|
||||
#define RING_BUFFER_CONTROL 0xc
|
||||
#define INTEL_RING_BUFFER_SIZE_MASK 0x000ff800
|
||||
#define INTEL_RING_BUFFER_ENABLED 1
|
||||
|
||||
#define INTEL_DISPLAY_HTOTAL 0x60000
|
||||
#define INTEL_DISPLAY_HBLANK 0x60004
|
||||
#define INTEL_DISPLAY_HSYNC 0x60008
|
||||
@@ -175,6 +204,22 @@ struct intel_free_graphics_memory {
|
||||
#define DISPLAY_MONITOR_POSITIVE_HSYNC (1UL << 3)
|
||||
#define DISPLAY_MONITOR_POSITIVE_VSYNC (2UL << 3)
|
||||
|
||||
// ring buffer commands
|
||||
|
||||
#define COMMAND_NOOP 0x00
|
||||
#define COMMAND_WAIT_FOR_EVENT (0x03 << 23)
|
||||
#define COMMAND_WAIT_FOR_OVERLAY_FLIP (1 << 16)
|
||||
|
||||
#define COMMAND_FLUSH (0x04 << 23)
|
||||
|
||||
// overlay flip
|
||||
#define COMMAND_OVERLAY_FLIP (0x11 << 23)
|
||||
#define COMMAND_OVERLAY_CONTINUE (0 << 21)
|
||||
#define COMMAND_OVERLAY_ON (1 << 21)
|
||||
#define COMMAND_OVERLAY_OFF (2 << 21)
|
||||
|
||||
// overlay
|
||||
|
||||
#define INTEL_OVERLAY_UPDATE 0x30000
|
||||
#define INTEL_OVERLAY_TEST 0x30004
|
||||
#define INTEL_OVERLAY_STATUS 0x30008
|
||||
@@ -232,14 +277,14 @@ struct overlay_registers {
|
||||
overlay_scale scale_uv;
|
||||
// (0x48) OCLRC0 - overlay color correction 0
|
||||
uint32 _reserved1 : 5;
|
||||
uint32 contrast_correction : 9;
|
||||
uint32 contrast_correction : 9; // fixed point: 3.6 bits
|
||||
uint32 _reserved2 : 10;
|
||||
uint32 brightness_correction : 8;
|
||||
uint32 brightness_correction : 8; // signed, -128 to 127
|
||||
// (0x4c) OCLRC1 - overlay color correction 1
|
||||
uint32 _reserved3 : 5;
|
||||
uint32 saturation_sin_correction : 11;
|
||||
uint32 saturation_sin_correction : 11; // signed fixed point: 3.7 bits
|
||||
uint32 _reserved4 : 6;
|
||||
uint32 saturation_cos_correction : 10;
|
||||
uint32 saturation_cos_correction : 10; // fixed point: 3.7 bits
|
||||
// (0x50) DCLRKV - destination color key value
|
||||
uint32 _reserved5 : 8;
|
||||
uint32 color_key_red : 8;
|
||||
|
||||
@@ -169,6 +169,8 @@ intel_init_accelerant(int device)
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
setup_ring_buffer(gInfo->shared_info->primary_ring_buffer, "intel primary ring buffer");
|
||||
|
||||
status = create_mode_list();
|
||||
if (status != B_OK) {
|
||||
uninit_common();
|
||||
|
||||
@@ -57,6 +57,9 @@ write32(uint32 offset, uint32 value)
|
||||
extern void enable_display_plane(bool enable);
|
||||
extern void set_display_power_mode(uint32 mode);
|
||||
|
||||
// engine.cpp
|
||||
extern void setup_ring_buffer(ring_buffer &ringBuffer, const char *name);
|
||||
|
||||
// modes.cpp
|
||||
extern status_t create_mode_list(void);
|
||||
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "accelerant.h"
|
||||
#include "accelerant_protos.h"
|
||||
#include "intel_extreme.h"
|
||||
|
||||
|
||||
//#define TRACE_ENGINE
|
||||
#define TRACE_ENGINE
|
||||
#ifdef TRACE_ENGINE
|
||||
extern "C" void _sPrintf(const char *format, ...);
|
||||
# define TRACE(x) _sPrintf x
|
||||
@@ -23,6 +23,56 @@ extern "C" void _sPrintf(const char *format, ...);
|
||||
static engine_token sEngineToken = {1, 0 /*B_2D_ACCELERATION*/, NULL};
|
||||
|
||||
|
||||
/** The ring buffer must be locked when calling this function */
|
||||
|
||||
static inline void
|
||||
write_to_ring(ring_buffer &ring, uint32 value)
|
||||
{
|
||||
uint32 *target = (uint32 *)(ring.base + ring.position);
|
||||
*target = value;
|
||||
|
||||
ring.position = (ring.position + sizeof(uint32)) & (ring.size - 1);
|
||||
}
|
||||
|
||||
|
||||
/** The ring buffer must be locked when calling this function */
|
||||
|
||||
static inline void
|
||||
ring_command_complete(ring_buffer &ring)
|
||||
{
|
||||
if (ring.position & 0x07) {
|
||||
// make sure the command is properly aligned
|
||||
write_to_ring(ring, COMMAND_NOOP);
|
||||
}
|
||||
|
||||
write32(ring.register_base + RING_BUFFER_TAIL, ring.position);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
setup_ring_buffer(ring_buffer &ringBuffer, const char *name)
|
||||
{
|
||||
TRACE(("Setup ring buffer %s, offset %lx, size %lx\n", name, ringBuffer.offset,
|
||||
ringBuffer.size));
|
||||
|
||||
if (init_lock(&ringBuffer.lock, name) < B_OK) {
|
||||
// disable ring buffer
|
||||
ringBuffer.size = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 ring = ringBuffer.register_base;
|
||||
write32(ring + RING_BUFFER_TAIL, 0);
|
||||
write32(ring + RING_BUFFER_START, ringBuffer.offset);
|
||||
write32(ring + RING_BUFFER_CONTROL,
|
||||
((ringBuffer.size - B_PAGE_SIZE) & INTEL_RING_BUFFER_SIZE_MASK)
|
||||
| INTEL_RING_BUFFER_ENABLED);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
/** Return number of hardware engines */
|
||||
|
||||
uint32
|
||||
|
||||
@@ -22,6 +22,15 @@ extern "C" void _sPrintf(const char *format, ...);
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
hide_overlay(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
uint32
|
||||
intel_overlay_count(const display_mode *mode)
|
||||
{
|
||||
@@ -33,7 +42,8 @@ intel_overlay_count(const display_mode *mode)
|
||||
const uint32 *
|
||||
intel_overlay_supported_spaces(const display_mode *mode)
|
||||
{
|
||||
static const uint32 kSupportedSpaces[] = {B_YCbCr422, 0};
|
||||
static const uint32 kSupportedSpaces[] = {B_RGB15, B_RGB16, B_RGB32,
|
||||
/*B_YCbCr411,*/ B_YCbCr422, 0};
|
||||
|
||||
return kSupportedSpaces;
|
||||
}
|
||||
@@ -52,20 +62,20 @@ const overlay_buffer *
|
||||
intel_allocate_overlay_buffer(color_space colorSpace, uint16 width,
|
||||
uint16 height)
|
||||
{
|
||||
uint32 bpp;
|
||||
uint32 bytesPerPixel;
|
||||
|
||||
switch (colorSpace) {
|
||||
case B_RGB15:
|
||||
bpp = 2;
|
||||
bytesPerPixel = 2;
|
||||
break;
|
||||
case B_RGB16:
|
||||
bpp = 2;
|
||||
bytesPerPixel = 2;
|
||||
break;
|
||||
case B_RGB32:
|
||||
bpp = 4;
|
||||
bytesPerPixel = 4;
|
||||
break;
|
||||
case B_YCbCr422:
|
||||
bpp = 2;
|
||||
bytesPerPixel = 2;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
@@ -83,7 +93,7 @@ intel_allocate_overlay_buffer(color_space colorSpace, uint16 width,
|
||||
buffer->space = colorSpace;
|
||||
buffer->width = width;
|
||||
buffer->height = height;
|
||||
buffer->bytes_per_row = (width * bpp + 0xf) & ~0xf;
|
||||
buffer->bytes_per_row = (width * bytesPerPixel + 0xf) & ~0xf;
|
||||
|
||||
status_t status = intel_allocate_memory(buffer->bytes_per_row * height,
|
||||
overlay->buffer_handle, overlay->buffer_offset);
|
||||
@@ -204,6 +214,15 @@ status_t
|
||||
intel_configure_overlay(overlay_token overlayToken, const overlay_buffer *buffer,
|
||||
const overlay_window *window, const overlay_view *view)
|
||||
{
|
||||
if (overlayToken != (overlay_token)gInfo->shared_info->overlay_token)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (window == NULL && view == NULL) {
|
||||
hide_overlay();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,20 @@ PhysicalMemoryMapper::Keep()
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
static void
|
||||
init_overlay_registers(overlay_registers *registers)
|
||||
{
|
||||
memset(registers, 0, B_PAGE_SIZE);
|
||||
|
||||
registers->contrast_correction = 0x20;
|
||||
registers->saturation_cos_correction = 0x40;
|
||||
// this by-passes contrast and saturation correction
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
status_t
|
||||
intel_extreme_init(intel_info &info)
|
||||
{
|
||||
@@ -130,6 +144,17 @@ intel_extreme_init(intel_info &info)
|
||||
if (info.memory_manager == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
// reserve ring buffer memory (currently, this memory is placed in
|
||||
// the graphics memory), but this could bring us problems with
|
||||
// write combining...
|
||||
ring_buffer &primary = info.shared_info->primary_ring_buffer;
|
||||
if (mem_alloc(info.memory_manager, B_PAGE_SIZE, &info,
|
||||
&primary.handle, &primary.offset) == B_OK) {
|
||||
primary.register_base = INTEL_PRIMARY_RING_BUFFER;
|
||||
primary.size = B_PAGE_SIZE;
|
||||
primary.base = info.shared_info->graphics_memory + primary.offset;
|
||||
}
|
||||
|
||||
// no errors, so keep mappings
|
||||
graphicsMapper.Keep();
|
||||
mmioMapper.Keep();
|
||||
@@ -156,7 +181,10 @@ intel_extreme_init(intel_info &info)
|
||||
#endif
|
||||
|
||||
// setup overlay registers
|
||||
info.overlay_registers = (overlay_registers *)((addr_t)info.shared_info + B_PAGE_SIZE);
|
||||
|
||||
info.overlay_registers = (overlay_registers *)((uint8 *)info.shared_info
|
||||
+ ROUND_TO_PAGE_SIZE(sizeof(intel_shared_info)));
|
||||
init_overlay_registers(info.overlay_registers);
|
||||
|
||||
physical_entry physicalEntry;
|
||||
get_memory_map(info.overlay_registers, sizeof(overlay_registers), &physicalEntry, 1);
|
||||
|
||||
Reference in New Issue
Block a user