Some work in progress:

* set_gtt_entry() used the wrong index to fill the GTT - this could have never
  worked correctly when you specified more memory than the amount of stolen
  memory.
* Implementing maintaining resources for emulating overlay using the 3D engine
  on i965. I don't yet commit the actual overlay code, as that is a) ugly, and
  b) does not work yet.
* Moved AreaKeeper into its own header.
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23709 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-01-23 17:50:27 +00:00
parent 53a1a99de7
commit 4dfa9e425f
8 changed files with 152 additions and 103 deletions
@@ -0,0 +1,73 @@
/*
* Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler, [email protected]
*/
#ifndef AREA_KEEPER_H
#define AREA_KEEPER_H
#include <KernelExport.h>
#include <OS.h>
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
@@ -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
@@ -15,6 +15,7 @@ Addon intel_extreme.accelerant :
memory.cpp
mode.cpp
overlay.cpp
overlay_3d_i965.cpp
: be libaccelerantscommon.a
;
@@ -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");
@@ -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;
@@ -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));
@@ -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[];
@@ -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 <driver_settings.h>
#include <util/kernel_cpp.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <driver_settings.h>
#include <util/kernel_cpp.h>
#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;
}