summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/drm/radeon/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/drm/radeon/core')
-rw-r--r--src/gallium/winsys/drm/radeon/core/SConscript4
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.c38
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.h18
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.c66
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.h27
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.c97
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.h7
7 files changed, 162 insertions, 95 deletions
diff --git a/src/gallium/winsys/drm/radeon/core/SConscript b/src/gallium/winsys/drm/radeon/core/SConscript
index 578174e32b..2ad68e403f 100644
--- a/src/gallium/winsys/drm/radeon/core/SConscript
+++ b/src/gallium/winsys/drm/radeon/core/SConscript
@@ -11,7 +11,9 @@ radeon_sources = [
env.Append(CPPPATH = '#/src/gallium/drivers/r300')
-env.ConvenienceLibrary(
+radeonwinsys = env.ConvenienceLibrary(
target ='radeonwinsys',
source = radeon_sources,
)
+
+Export('radeonwinsys')
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
index a15487352b..775bda8308 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
@@ -1,8 +1,8 @@
-/*
+/*
* Copyright © 2008 Jérôme Glisse
* 2009 Corbin Simpson
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -10,14 +10,14 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
* AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* The above copyright notice and this permission notice (including the
@@ -72,6 +72,7 @@ static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws,
alignment, domain, 0);
if (radeon_buffer->bo == NULL) {
FREE(radeon_buffer);
+ return NULL;
}
return &radeon_buffer->base;
}
@@ -93,6 +94,29 @@ static struct pipe_buffer *radeon_buffer_user_create(struct pipe_winsys *ws,
return &radeon_buffer->base;
}
+static struct pipe_buffer *radeon_surface_buffer_create(struct pipe_winsys *ws,
+ unsigned width,
+ unsigned height,
+ enum pipe_format format,
+ unsigned usage,
+ unsigned *stride)
+{
+ struct pipe_format_block block;
+ unsigned nblocksx, nblocksy, size;
+
+ pf_get_block(format, &block);
+
+ nblocksx = pf_get_nblocksx(&block, width);
+ nblocksy = pf_get_nblocksy(&block, height);
+
+ /* Radeons enjoy things in multiples of 32. */
+ /* XXX this can be 32 when POT */
+ *stride = (nblocksx * block.size + 63) & ~63;
+ size = *stride * nblocksy;
+
+ return radeon_buffer_create(ws, 64, usage, size);
+}
+
static void radeon_buffer_del(struct pipe_buffer *buffer)
{
struct radeon_pipe_buffer *radeon_buffer =
@@ -118,6 +142,8 @@ static void *radeon_buffer_map(struct pipe_winsys *ws,
write = 1;
}
+ radeon_bo_wait(radeon_buffer->bo);
+
if (radeon_bo_map(radeon_buffer->bo, write))
return NULL;
return radeon_buffer->bo->ptr;
@@ -175,15 +201,17 @@ struct radeon_winsys* radeon_pipe_winsys(int fd)
return NULL;
}
+ radeon_ws->priv->fd = fd;
radeon_ws->priv->bom = radeon_bo_manager_gem_ctor(fd);
radeon_ws->base.flush_frontbuffer = radeon_flush_frontbuffer;
radeon_ws->base.buffer_create = radeon_buffer_create;
- radeon_ws->base.buffer_destroy = radeon_buffer_del;
radeon_ws->base.user_buffer_create = radeon_buffer_user_create;
+ radeon_ws->base.surface_buffer_create = radeon_surface_buffer_create;
radeon_ws->base.buffer_map = radeon_buffer_map;
radeon_ws->base.buffer_unmap = radeon_buffer_unmap;
+ radeon_ws->base.buffer_destroy = radeon_buffer_del;
radeon_ws->base.fence_reference = radeon_fence_reference;
radeon_ws->base.fence_signalled = radeon_fence_signalled;
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
index ca8bbb3c11..f5153b06af 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
@@ -1,7 +1,7 @@
-/*
+/*
* Copyright © 2008 Jérôme Glisse
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -9,14 +9,14 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
* AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* The above copyright notice and this permission notice (including the
@@ -48,19 +48,19 @@
struct radeon_pipe_buffer {
struct pipe_buffer base;
struct radeon_bo *bo;
+ boolean flinked;
+ uint32_t flink;
};
#define RADEON_MAX_BOS 24
struct radeon_winsys_priv {
+ /* DRM FD */
+ int fd;
+
/* Radeon BO manager. */
struct radeon_bo_manager* bom;
- /* Radeon BO space checker. */
- struct radeon_cs_space_check sc[RADEON_MAX_BOS];
- /* Current BO count. */
- unsigned bo_count;
-
/* Radeon CS manager. */
struct radeon_cs_manager* csm;
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
index 428d3f65a1..8d818cf830 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
@@ -1,7 +1,7 @@
-/*
+/*
* Copyright © 2009 Corbin Simpson
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -9,14 +9,14 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
* AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* The above copyright notice and this permission notice (including the
@@ -31,7 +31,8 @@
#include "radeon_drm.h"
/* Create a pipe_screen. */
-struct pipe_screen* radeon_create_screen(int drmFB,
+struct pipe_screen* radeon_create_screen(struct drm_api* api,
+ int drmFB,
struct drm_create_screen_arg *arg)
{
struct radeon_winsys* winsys = radeon_pipe_winsys(drmFB);
@@ -46,25 +47,30 @@ struct pipe_screen* radeon_create_screen(int drmFB,
}
/* Create a pipe_context. */
-struct pipe_context* radeon_create_context(struct pipe_screen* screen)
+struct pipe_context* radeon_create_context(struct drm_api* api,
+ struct pipe_screen* screen)
{
if (getenv("RADEON_SOFTPIPE")) {
return radeon_create_softpipe(screen->winsys);
} else {
- return r300_create_context(screen, screen->winsys);
+ return r300_create_context(screen,
+ (struct r300_winsys*)screen->winsys);
}
}
-boolean radeon_buffer_from_texture(struct pipe_texture* texture,
+boolean radeon_buffer_from_texture(struct drm_api* api,
+ struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride)
{
- return FALSE;
+ /* XXX fix this */
+ return r300_get_texture_buffer(texture, buffer, stride);
}
/* Create a buffer from a handle. */
/* XXX what's up with name? */
-struct pipe_buffer* radeon_buffer_from_handle(struct pipe_screen* screen,
+struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api,
+ struct pipe_screen* screen,
const char* name,
unsigned handle)
{
@@ -91,7 +97,8 @@ struct pipe_buffer* radeon_buffer_from_handle(struct pipe_screen* screen,
return &radeon_buffer->base;
}
-boolean radeon_handle_from_buffer(struct pipe_screen* screen,
+boolean radeon_handle_from_buffer(struct drm_api* api,
+ struct pipe_screen* screen,
struct pipe_buffer* buffer,
unsigned* handle)
{
@@ -101,23 +108,50 @@ boolean radeon_handle_from_buffer(struct pipe_screen* screen,
return TRUE;
}
-boolean radeon_global_handle_from_buffer(struct pipe_screen* screen,
+boolean radeon_global_handle_from_buffer(struct drm_api* api,
+ struct pipe_screen* screen,
struct pipe_buffer* buffer,
unsigned* handle)
{
- /* XXX WTF is the difference here? global? */
+ int retval, fd;
+ struct drm_gem_flink flink;
struct radeon_pipe_buffer* radeon_buffer =
(struct radeon_pipe_buffer*)buffer;
- *handle = radeon_buffer->bo->handle;
+
+ if (!radeon_buffer->flinked) {
+ fd = ((struct radeon_winsys*)screen->winsys)->priv->fd;
+
+ flink.handle = radeon_buffer->bo->handle;
+
+ retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
+ if (retval) {
+ debug_printf("radeon: DRM_IOCTL_GEM_FLINK failed, error %d\n",
+ retval);
+ return FALSE;
+ }
+
+ radeon_buffer->flink = flink.name;
+ radeon_buffer->flinked = TRUE;
+ }
+
+ *handle = radeon_buffer->flink;
return TRUE;
}
struct drm_api drm_api_hooks = {
.create_screen = radeon_create_screen,
.create_context = radeon_create_context,
- /* XXX fix this */
- .buffer_from_texture = r300_get_texture_buffer,
+ .buffer_from_texture = radeon_buffer_from_texture,
.buffer_from_handle = radeon_buffer_from_handle,
.handle_from_buffer = radeon_handle_from_buffer,
.global_handle_from_buffer = radeon_global_handle_from_buffer,
};
+
+struct drm_api* drm_api_create()
+{
+#ifdef DEBUG
+ return trace_drm_create(&drm_api_hooks);
+#else
+ return &drm_api_hooks;
+#endif
+}
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
index 049f9984db..88a5c82b28 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
@@ -30,8 +30,13 @@
#ifndef RADEON_DRM_H
#define RADEON_DRM_H
+#include <sys/ioctl.h>
+
+#include "xf86drm.h"
+
#include "pipe/p_screen.h"
+#include "trace/tr_drm.h"
#include "util/u_memory.h"
#include "state_tracker/drm_api.h"
@@ -40,25 +45,35 @@
#include "radeon_r300.h"
#include "radeon_winsys_softpipe.h"
-struct pipe_screen* radeon_create_screen(int drmFB,
+/* XXX */
+#include "r300_screen.h"
+
+struct pipe_screen* radeon_create_screen(struct drm_api* api,
+ int drmFB,
struct drm_create_screen_arg *arg);
-struct pipe_context* radeon_create_context(struct pipe_screen* screen);
+struct pipe_context* radeon_create_context(struct drm_api* api,
+ struct pipe_screen* screen);
-boolean radeon_buffer_from_texture(struct pipe_texture* texture,
+boolean radeon_buffer_from_texture(struct drm_api* api,
+ struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride);
-struct pipe_buffer* radeon_buffer_from_handle(struct pipe_screen* screen,
+struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api,
+ struct pipe_screen* screen,
const char* name,
unsigned handle);
-boolean radeon_handle_from_buffer(struct pipe_screen* screen,
+boolean radeon_handle_from_buffer(struct drm_api* api,
+ struct pipe_screen* screen,
struct pipe_buffer* buffer,
unsigned* handle);
-boolean radeon_global_handle_from_buffer(struct pipe_screen* screen,
+boolean radeon_global_handle_from_buffer(struct drm_api* api,
+ struct pipe_screen* screen,
struct pipe_buffer* buffer,
unsigned* handle);
+void radeon_destroy_drm_api(struct drm_api* api);
#endif
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
index da233203d7..4e9a2ddd16 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
@@ -22,54 +22,30 @@
#include "radeon_r300.h"
-static void radeon_r300_add_buffer(struct r300_winsys* winsys,
- struct pipe_buffer* pbuffer,
- uint32_t rd,
- uint32_t wd)
+static boolean radeon_r300_add_buffer(struct r300_winsys* winsys,
+ struct pipe_buffer* pbuffer,
+ uint32_t rd,
+ uint32_t wd)
{
- int i;
struct radeon_winsys_priv* priv =
(struct radeon_winsys_priv*)winsys->radeon_winsys;
- struct radeon_cs_space_check* sc = priv->sc;
struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo;
- /* Check to see if this BO is already in line for validation;
- * find a slot for it otherwise. */
- for (i = 0; i < RADEON_MAX_BOS; i++) {
- if (sc[i].bo == bo) {
- return;
- } else if (sc[i].bo == NULL) {
- sc[i].bo = bo;
- sc[i].read_domains = rd;
- sc[i].write_domain = wd;
- priv->bo_count = i + 1;
- return;
- }
- }
-
- assert(FALSE && "Oh God too many BOs!");
+ radeon_cs_space_add_persistent_bo(priv->cs, bo, rd, wd);
+ return TRUE;
}
static boolean radeon_r300_validate(struct r300_winsys* winsys)
{
- int retval;
struct radeon_winsys_priv* priv =
(struct radeon_winsys_priv*)winsys->radeon_winsys;
- struct radeon_cs_space_check* sc = priv->sc;
-
- retval = radeon_cs_space_check(priv->cs, sc, priv->bo_count);
- if (retval == RADEON_CS_SPACE_OP_TO_BIG) {
- /* We might as well HCF, since this is not going to fit in the card,
- * period. */
- exit(1);
- } else if (retval == RADEON_CS_SPACE_FLUSH) {
- /* We must flush before more rendering can commence. */
- return TRUE;
+ if (radeon_cs_space_check(priv->cs) < 0) {
+ return FALSE;
}
/* Things are fine, we can proceed as normal. */
- return FALSE;
+ return TRUE;
}
static boolean radeon_r300_check_cs(struct r300_winsys* winsys, int size)
@@ -108,9 +84,15 @@ static void radeon_r300_write_cs_reloc(struct r300_winsys* winsys,
{
struct radeon_winsys_priv* priv =
(struct radeon_winsys_priv*)winsys->radeon_winsys;
+ int retval = 0;
- radeon_cs_write_reloc(priv->cs,
+ retval = radeon_cs_write_reloc(priv->cs,
((struct radeon_pipe_buffer*)pbuffer)->bo, rd, wd, flags);
+
+ if (retval) {
+ debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n",
+ pbuffer, rd, wd, flags);
+ }
}
static void radeon_r300_end_cs(struct r300_winsys* winsys,
@@ -128,57 +110,56 @@ static void radeon_r300_flush_cs(struct r300_winsys* winsys)
{
struct radeon_winsys_priv* priv =
(struct radeon_winsys_priv*)winsys->radeon_winsys;
- int retval = 0;
+ int retval;
+ /* Emit the CS. */
retval = radeon_cs_emit(priv->cs);
if (retval) {
debug_printf("radeon: Bad CS, dumping...\n");
radeon_cs_print(priv->cs, stderr);
}
+
+ /* Clean out BOs. */
+ radeon_cs_space_reset_bos(priv->cs);
+
+ /* Reset CS.
+ * Someday, when we care about performance, we should really find a way
+ * to rotate between two or three CS objects so that the GPU can be
+ * spinning through one CS while another one is being filled. */
radeon_cs_erase(priv->cs);
}
/* Helper function to do the ioctls needed for setup and init. */
static void do_ioctls(struct r300_winsys* winsys, int fd)
{
- struct drm_radeon_gem_info info;
- drm_radeon_getparam_t gp;
- int target;
+ struct drm_radeon_gem_info gem_info = {0};
+ struct drm_radeon_info info = {0};
+ int target = 0;
int retval;
- gp.value = &target;
-
- /* First, get the number of pixel pipes */
- gp.param = RADEON_PARAM_NUM_GB_PIPES;
- retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp));
- if (retval) {
- fprintf(stderr, "%s: Failed to get GB pipe count, error number %d\n",
- __FUNCTION__, retval);
- exit(1);
- }
- winsys->gb_pipes = target;
+ info.value = &target;
- /* Then, get PCI ID */
- gp.param = RADEON_PARAM_DEVICE_ID;
- retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp));
+ /* First, get PCI ID */
+ info.request = RADEON_INFO_DEVICE_ID;
+ retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
if (retval) {
- fprintf(stderr, "%s: Failed to get PCI ID, error number %d\n",
- __FUNCTION__, retval);
+ fprintf(stderr, "%s: Failed to get PCI ID, "
+ "error number %d\n", __FUNCTION__, retval);
exit(1);
}
winsys->pci_id = target;
- /* Finally, retrieve MM info */
+ /* Then, retrieve MM info */
retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO,
- &info, sizeof(info));
+ &gem_info, sizeof(gem_info));
if (retval) {
fprintf(stderr, "%s: Failed to get MM info, error number %d\n",
__FUNCTION__, retval);
exit(1);
}
- winsys->gart_size = info.gart_size;
+ winsys->gart_size = gem_info.gart_size;
/* XXX */
- winsys->vram_size = info.vram_visible;
+ winsys->vram_size = gem_info.vram_visible;
}
struct r300_winsys*
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h
index 5c373cd084..741c137188 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h
@@ -20,6 +20,9 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
+#ifndef RADEON_R300_H
+#define RADEON_R300_H
+
/* XXX WTF is this! I shouldn't have to include those first three! FUCK! */
#include <stdint.h>
#include <stdlib.h>
@@ -31,5 +34,9 @@
#include "radeon_buffer.h"
+struct radeon_winsys;
+
struct r300_winsys*
radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys);
+
+#endif /* RADEON_R300_H */