diff --git a/headers/private/graphics/intel_extreme/AreaKeeper.h b/headers/private/graphics/intel_extreme/AreaKeeper.h new file mode 100644 index 0000000000..ba4744e88c --- /dev/null +++ b/headers/private/graphics/intel_extreme/AreaKeeper.h @@ -0,0 +1,73 @@ +/* + * Copyright 2006-2008, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + */ +#ifndef AREA_KEEPER_H +#define AREA_KEEPER_H + + +#include +#include + + +class AreaKeeper { + public: + AreaKeeper(); + ~AreaKeeper(); + + area_id Create(const char *name, void **_virtualAddress, uint32 spec, + size_t size, uint32 lock, uint32 protection); + area_id Map(const char *name, void *physicalAddress, size_t numBytes, + uint32 spec, uint32 protection, void **_virtualAddress); + + status_t InitCheck() { return fArea < B_OK ? (status_t)fArea : B_OK; } + void Detach(); + + private: + area_id fArea; +}; + + +AreaKeeper::AreaKeeper() + : + fArea(-1) +{ +} + + +AreaKeeper::~AreaKeeper() +{ + if (fArea >= B_OK) + delete_area(fArea); +} + + +area_id +AreaKeeper::Create(const char *name, void **_virtualAddress, uint32 spec, + size_t size, uint32 lock, uint32 protection) +{ + fArea = create_area(name, _virtualAddress, spec, size, lock, protection); + return fArea; +} + + +area_id +AreaKeeper::Map(const char *name, void *physicalAddress, size_t numBytes, + uint32 spec, uint32 protection, void **_virtualAddress) +{ + fArea = map_physical_memory(name, physicalAddress, numBytes, spec, protection, + _virtualAddress); + return fArea; +} + + +void +AreaKeeper::Detach() +{ + fArea = -1; +} + +#endif // AREA_KEEPER_H diff --git a/headers/private/graphics/intel_extreme/intel_extreme.h b/headers/private/graphics/intel_extreme/intel_extreme.h index 0f2821809b..d321151533 100644 --- a/headers/private/graphics/intel_extreme/intel_extreme.h +++ b/headers/private/graphics/intel_extreme/intel_extreme.h @@ -1,5 +1,5 @@ /* - * Copyright 2006-2007, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2008, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -179,6 +179,7 @@ struct intel_free_graphics_memory { #define G33_GTT_2M (2 << 8) #define GTT_ENTRY_VALID 0x01 #define GTT_ENTRY_LOCAL_MEMORY 0x02 +#define GTT_PAGE_SHIFT 12 // interrupts #define INTEL_INTERRUPT_ENABLED 0x020a0 diff --git a/src/add-ons/accelerants/intel_extreme/Jamfile b/src/add-ons/accelerants/intel_extreme/Jamfile index e350fefd10..4fd5c3a0db 100644 --- a/src/add-ons/accelerants/intel_extreme/Jamfile +++ b/src/add-ons/accelerants/intel_extreme/Jamfile @@ -15,6 +15,7 @@ Addon intel_extreme.accelerant : memory.cpp mode.cpp overlay.cpp + overlay_3d_i965.cpp : be libaccelerantscommon.a ; diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.cpp b/src/add-ons/accelerants/intel_extreme/accelerant.cpp index 2e7d005caf..cb90cf1d79 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.cpp +++ b/src/add-ons/accelerants/intel_extreme/accelerant.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2008, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -79,10 +79,9 @@ AreaCloner::Keep() // #pragma mark - -/** This is the common accelerant_info initializer. It is called by - * both, the first accelerant and all clones. - */ - +/*! This is the common accelerant_info initializer. It is called by + both, the first accelerant and all clones. +*/ static status_t init_common(int device, bool isClone) { @@ -102,16 +101,16 @@ init_common(int device, bool isClone) intel_get_private_data data; data.magic = INTEL_PRIVATE_DATA_MAGIC; - if (ioctl(device, INTEL_GET_PRIVATE_DATA, &data, sizeof(intel_get_private_data)) != 0) { + if (ioctl(device, INTEL_GET_PRIVATE_DATA, &data, + sizeof(intel_get_private_data)) != 0) { free(gInfo); return B_ERROR; } AreaCloner sharedCloner; gInfo->shared_info_area = sharedCloner.Clone("intel extreme shared info", - (void **)&gInfo->shared_info, B_ANY_ADDRESS, - B_READ_AREA | B_WRITE_AREA, - data.shared_info_area); + (void **)&gInfo->shared_info, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, + data.shared_info_area); status_t status = sharedCloner.InitCheck(); if (status < B_OK) { free(gInfo); @@ -120,9 +119,8 @@ init_common(int device, bool isClone) AreaCloner regsCloner; gInfo->regs_area = regsCloner.Clone("intel extreme regs", - (void **)&gInfo->regs, B_ANY_ADDRESS, - B_READ_AREA | B_WRITE_AREA, - gInfo->shared_info->registers_area); + (void **)&gInfo->regs, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, + gInfo->shared_info->registers_area); status = regsCloner.InitCheck(); if (status < B_OK) { free(gInfo); @@ -142,15 +140,22 @@ init_common(int device, bool isClone) if (gInfo->shared_info->hardware_cursor_enabled) gInfo->cursor_memory = (uint8 *)gInfo->overlay_registers + 2 * B_PAGE_SIZE; + if (gInfo->shared_info->device_type == (INTEL_TYPE_9xx | INTEL_TYPE_965)) { + // allocate some extra memory for the 3D context + intel_allocate_memory(INTEL_i965_3D_CONTEXT_SIZE, gInfo->context_handle, + gInfo->context_offset); + } + return B_OK; } -/** Clean up data common to both primary and cloned accelerant */ - +/*! Clean up data common to both primary and cloned accelerant */ static void uninit_common(void) { + intel_free_memory(gInfo->context_handle); + delete_area(gInfo->regs_area); delete_area(gInfo->shared_info_area); @@ -167,8 +172,7 @@ uninit_common(void) // #pragma mark - public accelerant functions -/** Init primary accelerant */ - +/*! Init primary accelerant */ status_t intel_init_accelerant(int device) { @@ -267,10 +271,9 @@ err1: } -/** This function is called for both, the primary accelerant and all of - * its clones. - */ - +/*! This function is called for both, the primary accelerant and all of + its clones. +*/ void intel_uninit_accelerant(void) { @@ -299,7 +302,8 @@ intel_get_accelerant_device_info(accelerant_device_info *info) info->version = B_ACCELERANT_VERSION; strcpy(info->name, - (gInfo->shared_info->device_type & INTEL_TYPE_FAMILY_MASK) == INTEL_TYPE_7xx + (gInfo->shared_info->device_type & INTEL_TYPE_FAMILY_MASK) + == INTEL_TYPE_7xx ? "Intel Extreme Graphics 1" : "Intel Extreme Graphics 2"); strcpy(info->chipset, gInfo->shared_info->device_identifier); strcpy(info->serial_no, "None"); diff --git a/src/add-ons/accelerants/intel_extreme/accelerant.h b/src/add-ons/accelerants/intel_extreme/accelerant.h index ded537084d..c4db067ea7 100644 --- a/src/add-ons/accelerants/intel_extreme/accelerant.h +++ b/src/add-ons/accelerants/intel_extreme/accelerant.h @@ -1,5 +1,5 @@ /* - * Copyright 2006-2007, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2008, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -19,6 +19,8 @@ struct overlay { overlay_buffer buffer; uint32 buffer_handle; uint32 buffer_offset; + uint32 state_handle; + uint32 state_offset; }; struct overlay_frame { @@ -54,6 +56,11 @@ struct accelerant_info { edid1_info edid_info; bool has_edid; + // limited 3D support for overlay on i965 + uint32 context_handle; + uint32 context_offset; + bool context_set; + int device; uint8 head_mode; bool is_clone; diff --git a/src/add-ons/accelerants/intel_extreme/overlay.cpp b/src/add-ons/accelerants/intel_extreme/overlay.cpp index bcba7cbcb4..fad2989689 100644 --- a/src/add-ons/accelerants/intel_extreme/overlay.cpp +++ b/src/add-ons/accelerants/intel_extreme/overlay.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2008, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -300,7 +300,13 @@ intel_overlay_count(const display_mode *mode) const uint32 * intel_overlay_supported_spaces(const display_mode *mode) { - static const uint32 kSupportedSpaces[] = {B_RGB15, B_RGB16, B_RGB32, B_YCbCr422, 0}; + static const uint32 kSupportedSpaces[] = {B_RGB15, B_RGB16, B_RGB32, + B_YCbCr422, 0}; + static const uint32 kSupportedi965Spaces[] = {B_YCbCr422, 0}; + intel_shared_info &sharedInfo = *gInfo->shared_info; + + if (sharedInfo.device_type == (INTEL_TYPE_9xx | INTEL_TYPE_965)) + return kSupportedi965Spaces; return kSupportedSpaces; } @@ -323,6 +329,7 @@ intel_allocate_overlay_buffer(color_space colorSpace, uint16 width, TRACE(("intel_allocate_overlay_buffer(width %u, height %u, colorSpace %lu)\n", width, height, colorSpace)); + intel_shared_info &sharedInfo = *gInfo->shared_info; uint32 bytesPerPixel; switch (colorSpace) { @@ -363,11 +370,25 @@ intel_allocate_overlay_buffer(color_space colorSpace, uint16 width, return NULL; } - buffer->buffer = gInfo->shared_info->graphics_memory + overlay->buffer_offset; - buffer->buffer_dma = gInfo->shared_info->physical_graphics_memory + overlay->buffer_offset; + if (sharedInfo.device_type == (INTEL_TYPE_9xx | INTEL_TYPE_965)) { + status = intel_allocate_memory(INTEL_i965_OVERLAY_STATE_SIZE, + overlay->state_handle, overlay->state_offset); + if (status < B_OK) { + intel_free_memory(overlay->buffer_handle); + free(overlay); + return NULL; + } + } else + overlay->state_handle = 0; - TRACE(("allocated overlay buffer: handle=%x, offset=%x, address=%x, physical address=%x\n", - overlay->buffer_handle, overlay->buffer_offset, buffer->buffer, buffer->buffer_dma)); + buffer->buffer = gInfo->shared_info->graphics_memory + + overlay->buffer_offset; + buffer->buffer_dma = gInfo->shared_info->physical_graphics_memory + + overlay->buffer_offset; + + TRACE(("allocated overlay buffer: handle=%x, offset=%x, address=%x, " + "physical address=%x\n", overlay->buffer_handle, overlay->buffer_offset, + buffer->buffer, buffer->buffer_dma)); return buffer; } @@ -386,6 +407,7 @@ intel_release_overlay_buffer(const overlay_buffer *buffer) hide_overlay(); intel_free_memory(overlay->buffer_handle); + intel_free_memory(overlay->state_handle); free(overlay); return B_OK; @@ -393,8 +415,8 @@ intel_release_overlay_buffer(const overlay_buffer *buffer) status_t -intel_get_overlay_constraints(const display_mode *mode, const overlay_buffer *buffer, - overlay_constraints *constraints) +intel_get_overlay_constraints(const display_mode *mode, + const overlay_buffer *buffer, overlay_constraints *constraints) { TRACE(("intel_get_overlay_constraints(buffer %p)\n", buffer)); diff --git a/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.h b/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.h index 16fddf38af..846766fb51 100644 --- a/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.h +++ b/src/add-ons/kernel/drivers/graphics/intel_extreme/driver.h @@ -1,5 +1,5 @@ /* - * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2008, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -20,9 +20,9 @@ #define read8(address) (*((volatile uint8 *)(address))) #define read16(address) (*((volatile uint16 *)(address))) #define read32(address) (*((volatile uint32 *)(address))) -#define write8(address,data) (*((volatile uint8 *)(address)) = data) -#define write16(address,data) (*((volatile uint16 *)(address)) = (data)) -#define write32(address,data) (*((volatile uint32 *)(address)) = (data)) +#define write8(address, data) (*((volatile uint8 *)(address)) = (data)) +#define write16(address, data) (*((volatile uint16 *)(address)) = (data)) +#define write32(address, data) (*((volatile uint32 *)(address)) = (data)) extern char *gDeviceNames[]; 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 188f118596..8fcce704b0 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 @@ -1,5 +1,5 @@ /* - * Copyright 2006-2007, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2008, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -8,17 +8,19 @@ #include "intel_extreme.h" + +#include "AreaKeeper.h" #include "driver.h" #include "utility.h" -#include -#include - #include #include #include #include +#include +#include + #define TRACE_DEVICE #ifdef TRACE_DEVICE @@ -28,67 +30,6 @@ #endif -class AreaKeeper { - public: - AreaKeeper(); - ~AreaKeeper(); - - area_id Create(const char *name, void **_virtualAddress, uint32 spec, - size_t size, uint32 lock, uint32 protection); - area_id Map(const char *name, void *physicalAddress, size_t numBytes, - uint32 spec, uint32 protection, void **_virtualAddress); - - status_t InitCheck() { return fArea < B_OK ? (status_t)fArea : B_OK; } - void Detach(); - - private: - area_id fArea; -}; - - -AreaKeeper::AreaKeeper() - : - fArea(-1) -{ -} - - -AreaKeeper::~AreaKeeper() -{ - if (fArea >= B_OK) - delete_area(fArea); -} - - -area_id -AreaKeeper::Create(const char *name, void **_virtualAddress, uint32 spec, - size_t size, uint32 lock, uint32 protection) -{ - fArea = create_area(name, _virtualAddress, spec, size, lock, protection); - return fArea; -} - - -area_id -AreaKeeper::Map(const char *name, void *physicalAddress, size_t numBytes, - uint32 spec, uint32 protection, void **_virtualAddress) -{ - fArea = map_physical_memory(name, physicalAddress, numBytes, spec, protection, - _virtualAddress); - return fArea; -} - - -void -AreaKeeper::Detach() -{ - fArea = -1; -} - - -// #pragma mark - - - static void init_overlay_registers(overlay_registers *registers) { @@ -147,7 +88,6 @@ determine_stolen_memory_size(intel_info &info) size_t memorySize = 1 << 20; // 1 MB size_t gttSize = 0; - // TODO: check if the GTT is really part of the stolen memory if (info.device_type == (INTEL_TYPE_9xx | INTEL_TYPE_965)) { switch (memoryConfig & i965_GTT_MASK) { case i965_GTT_128K: @@ -236,7 +176,7 @@ determine_stolen_memory_size(intel_info &info) static void set_gtt_entry(intel_info &info, uint32 offset, uint8 *physicalAddress) { - write32(info.gtt_base + (offset >> 10), + write32(info.gtt_base + (offset >> GTT_PAGE_SHIFT), (uint32)physicalAddress | GTT_ENTRY_VALID); } @@ -247,7 +187,8 @@ release_vblank_sem(intel_info &info) int32 count; if (get_sem_count(info.shared_info->vblank_sem, &count) == B_OK && count < 0) { - release_sem_etc(info.shared_info->vblank_sem, -count, B_DO_NOT_RESCHEDULE); + release_sem_etc(info.shared_info->vblank_sem, -count, + B_DO_NOT_RESCHEDULE); return B_INVOKE_SCHEDULER; }