From 7740a4c15bd6ee7fd66388b5fc21c786b926429d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 28 Apr 2006 16:50:39 +0000 Subject: [PATCH] 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 --- .../graphics/intel_extreme/intel_extreme.h | 53 ++++++++++++++++-- .../accelerants/intel_extreme/accelerant.cpp | 2 + .../accelerants/intel_extreme/accelerant.h | 3 ++ .../accelerants/intel_extreme/engine.cpp | 54 ++++++++++++++++++- .../accelerants/intel_extreme/overlay.cpp | 33 +++++++++--- .../graphics/intel_extreme/intel_extreme.cpp | 30 ++++++++++- 6 files changed, 161 insertions(+), 14 deletions(-) diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index d355d63b90..ef7ef40e98 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -9,6 +9,8 @@ #define INTEL_EXTREME_H +#include "lock.h" + #include #include @@ -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; diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.cpp b/src/add-ons/accelerants/intel_extreme/accelerant.cpp index def20b6c94..ef2a43b04c 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.cpp +++ b/src/add-ons/accelerants/intel_extreme/accelerant.cpp @@ -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(); diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.h b/src/add-ons/accelerants/intel_extreme/accelerant.h index 1702eabec7..16d2c12184 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.h +++ b/src/add-ons/accelerants/intel_extreme/accelerant.h @@ -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); diff --git a/src/add-ons/accelerants/intel_extreme/engine.cpp b/src/add-ons/accelerants/intel_extreme/engine.cpp index 4fcda44eee..e99a6607ce 100644 --- a/src/add-ons/accelerants/intel_extreme/engine.cpp +++ b/src/add-ons/accelerants/intel_extreme/engine.cpp @@ -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 diff --git a/src/add-ons/accelerants/intel_extreme/overlay.cpp b/src/add-ons/accelerants/intel_extreme/overlay.cpp index abdc723759..6ab6ada4e3 100644 --- a/src/add-ons/accelerants/intel_extreme/overlay.cpp +++ b/src/add-ons/accelerants/intel_extreme/overlay.cpp @@ -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; } diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp index d5e7efd388..0dad64ac2a 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/intel_extreme.cpp @@ -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);