summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/radeon
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/radeon')
-rw-r--r--src/mesa/drivers/dri/radeon/common_context.h29
-rw-r--r--src/mesa/drivers/dri/radeon/common_lock.c2
-rw-r--r--src/mesa/drivers/dri/radeon/common_lock.h23
-rw-r--r--src/mesa/drivers/dri/radeon/common_misc.c112
-rw-r--r--src/mesa/drivers/dri/radeon/common_misc.h6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_cs_legacy.h2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c1
7 files changed, 159 insertions, 16 deletions
diff --git a/src/mesa/drivers/dri/radeon/common_context.h b/src/mesa/drivers/dri/radeon/common_context.h
index e4d210392c..eb95dc9d75 100644
--- a/src/mesa/drivers/dri/radeon/common_context.h
+++ b/src/mesa/drivers/dri/radeon/common_context.h
@@ -1,6 +1,14 @@
#ifndef COMMON_CONTEXT_H
#define COMMON_CONTEXT_H
+
+#include "main/mm.h"
+#include "math/m_vector.h"
+#include "texmem.h"
+#include "tnl/t_context.h"
+#include "main/colormac.h"
+
+
/* This union is used to avoid warnings/miscompilation
with float to uint32_t casts due to strict-aliasing */
typedef union { GLfloat f; uint32_t ui32; } float_ui32_type;
@@ -9,11 +17,6 @@ struct radeon_context;
typedef struct radeon_context radeonContextRec;
typedef struct radeon_context *radeonContextPtr;
-#include "main/mm.h"
-#include "math/m_vector.h"
-#include "texmem.h"
-#include "tnl/t_context.h"
-
#define TEX_0 0x1
#define TEX_1 0x2
@@ -256,6 +259,20 @@ struct radeon_state {
struct radeon_stencilbuffer_state stencil;
};
+/**
+ * This structure holds the command buffer while it is being constructed.
+ *
+ * The first batch of commands in the buffer is always the state that needs
+ * to be re-emitted when the context is lost. This batch can be skipped
+ * otherwise.
+ */
+struct radeon_cmdbuf {
+ struct radeon_cs_manager *csm;
+ struct radeon_cs *cs;
+ int size; /** # of dwords total */
+ unsigned int flushing:1; /** whether we're currently in FlushCmdBufLocked */
+};
+
struct radeon_context {
GLcontext *glCtx;
radeonScreenPtr radeonScreen; /* Screen private DRI data */
@@ -308,6 +325,8 @@ struct radeon_context {
*/
driOptionCache optionCache;
+ struct radeon_cmdbuf cmdbuf;
+
struct {
void (*get_lock)(radeonContextPtr radeon);
void (*update_viewport_offset)(GLcontext *ctx);
diff --git a/src/mesa/drivers/dri/radeon/common_lock.c b/src/mesa/drivers/dri/radeon/common_lock.c
index d983e8ce92..09517450a9 100644
--- a/src/mesa/drivers/dri/radeon/common_lock.c
+++ b/src/mesa/drivers/dri/radeon/common_lock.c
@@ -84,7 +84,7 @@ void radeonUpdatePageFlipping(radeonContextPtr rmesa)
#else
/* Turn on/off page flipping according to the flags in the sarea:
*/
-static void radeonUpdatePageFlipping(radeonContextPtr rmesa)
+void radeonUpdatePageFlipping(radeonContextPtr rmesa)
{
rmesa->doPageFlip = rmesa->sarea->pfState;
if (rmesa->glCtx->WinSysDrawBuffer) {
diff --git a/src/mesa/drivers/dri/radeon/common_lock.h b/src/mesa/drivers/dri/radeon/common_lock.h
index 50a4a0b05a..431b076f02 100644
--- a/src/mesa/drivers/dri/radeon/common_lock.h
+++ b/src/mesa/drivers/dri/radeon/common_lock.h
@@ -41,6 +41,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef COMMON_LOCK_H
#define COMMON_LOCK_H
+
+#include "main/colormac.h"
+#include "radeon_screen.h"
+#include "common_context.h"
+
extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags);
/* Turn DEBUG_LOCKING on to find locking conflicts.
@@ -93,19 +98,23 @@ extern int prevLockLine;
do { \
char __ret = 0; \
DEBUG_CHECK_LOCK(); \
- DRM_CAS( (rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \
- (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret ); \
- if ( __ret ) \
+ if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \
+ DRM_CAS( (rmesa)->dri.hwLock, (rmesa)->dri.hwContext, \
+ (DRM_LOCK_HELD | (rmesa)->dri.hwContext), __ret ); \
+ if ( __ret ) \
radeonGetLock( (rmesa), 0 ); \
+ } \
DEBUG_LOCK(); \
} while (0)
#define UNLOCK_HARDWARE( rmesa ) \
do { \
- DRM_UNLOCK( (rmesa)->dri.fd, \
- (rmesa)->dri.hwLock, \
- (rmesa)->dri.hwContext ); \
- DEBUG_RESET(); \
+ if (!(rmesa)->radeonScreen->driScreen->dri2.enabled) { \
+ DRM_UNLOCK( (rmesa)->dri.fd, \
+ (rmesa)->dri.hwLock, \
+ (rmesa)->dri.hwContext ); \
+ DEBUG_RESET(); \
+ } \
} while (0)
#endif
diff --git a/src/mesa/drivers/dri/radeon/common_misc.c b/src/mesa/drivers/dri/radeon/common_misc.c
index eab9cc74e3..ba3c76daa9 100644
--- a/src/mesa/drivers/dri/radeon/common_misc.c
+++ b/src/mesa/drivers/dri/radeon/common_misc.c
@@ -51,11 +51,16 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "drirenderbuffer.h"
#include "vblank.h"
-
+#include "radeon_bo.h"
+#include "radeon_cs.h"
+#include "radeon_bo_legacy.h"
+#include "radeon_cs_legacy.h"
+#include "radeon_bo_gem.h"
+#include "radeon_cs_gem.h"
#include "dri_util.h"
#include "radeon_drm.h"
-#include "radeon_screen.h"
#include "radeon_buffer.h"
+#include "radeon_screen.h"
#include "common_context.h"
#include "common_misc.h"
#include "common_lock.h"
@@ -577,3 +582,106 @@ void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
}
}
+/* cmdbuffer */
+/**
+ * Send the current command buffer via ioctl to the hardware.
+ */
+int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller)
+{
+ int ret = 0;
+
+ if (rmesa->cmdbuf.flushing) {
+ fprintf(stderr, "Recursive call into r300FlushCmdBufLocked!\n");
+ exit(-1);
+ }
+ rmesa->cmdbuf.flushing = 1;
+ if (rmesa->cmdbuf.cs->cdw) {
+ ret = radeon_cs_emit(rmesa->cmdbuf.cs);
+ rmesa->vtbl.set_all_dirty(rmesa->glCtx);
+ }
+ radeon_cs_erase(rmesa->cmdbuf.cs);
+ rmesa->cmdbuf.flushing = 0;
+ return ret;
+}
+
+int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller)
+{
+ int ret;
+
+ LOCK_HARDWARE(rmesa);
+ ret = rcommonFlushCmdBufLocked(rmesa, caller);
+ UNLOCK_HARDWARE(rmesa);
+
+ if (ret) {
+ fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret);
+ _mesa_exit(ret);
+ }
+
+ return ret;
+}
+
+/**
+ * Make sure that enough space is available in the command buffer
+ * by flushing if necessary.
+ *
+ * \param dwords The number of dwords we need to be free on the command buffer
+ */
+void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller)
+{
+ if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size ||
+ radeon_cs_need_flush(rmesa->cmdbuf.cs)) {
+ rcommonFlushCmdBuf(rmesa, caller);
+ }
+}
+
+void rcommonInitCmdBuf(radeonContextPtr rmesa, int max_state_size)
+{
+ GLuint size;
+ /* Initialize command buffer */
+ size = 256 * driQueryOptioni(&rmesa->optionCache,
+ "command_buffer_size");
+ if (size < 2 * max_state_size) {
+ size = 2 * max_state_size + 65535;
+ }
+ if (size > 64 * 256)
+ size = 64 * 256;
+
+ size = 64 * 1024 / 4;
+
+ if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) {
+ fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%zd\n",
+ sizeof(drm_r300_cmd_header_t));
+ fprintf(stderr, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n",
+ sizeof(drm_radeon_cmd_buffer_t));
+ fprintf(stderr,
+ "Allocating %d bytes command buffer (max state is %d bytes)\n",
+ size * 4, max_state_size * 4);
+ }
+
+ if (rmesa->radeonScreen->kernel_mm) {
+ int fd = rmesa->radeonScreen->driScreen->fd;
+ rmesa->cmdbuf.csm = radeon_cs_manager_gem_ctor(fd);
+ } else {
+ rmesa->cmdbuf.csm = radeon_cs_manager_legacy_ctor(rmesa);
+ }
+ if (rmesa->cmdbuf.csm == NULL) {
+ /* FIXME: fatal error */
+ return;
+ }
+ rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size);
+ assert(rmesa->cmdbuf.cs != NULL);
+ rmesa->cmdbuf.size = size;
+
+}
+/**
+ * Destroy the command buffer
+ */
+void rcommonDestroyCmdBuf(radeonContextPtr rmesa)
+{
+ radeon_cs_destroy(rmesa->cmdbuf.cs);
+ if (rmesa->radeonScreen->driScreen->dri2.enabled || rmesa->radeonScreen->kernel_mm) {
+ radeon_cs_manager_gem_dtor(rmesa->cmdbuf.csm);
+ } else {
+ radeon_cs_manager_legacy_dtor(rmesa->cmdbuf.csm);
+ }
+}
diff --git a/src/mesa/drivers/dri/radeon/common_misc.h b/src/mesa/drivers/dri/radeon/common_misc.h
index cc4832c75e..7057ad941f 100644
--- a/src/mesa/drivers/dri/radeon/common_misc.h
+++ b/src/mesa/drivers/dri/radeon/common_misc.h
@@ -1,6 +1,7 @@
#ifndef COMMON_MISC_H
#define COMMON_MISC_H
+#include "common_context.h"
void radeonRecalcScissorRects(radeonContextPtr radeon);
void radeonSetCliprects(radeonContextPtr radeon);
void radeonUpdateScissor( GLcontext *ctx );
@@ -17,4 +18,9 @@ void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
void radeonUpdatePageFlipping(radeonContextPtr rmesa);
+void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller);
+int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller);
+int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller);
+void rcommonInitCmdBuf(radeonContextPtr rmesa, int max_state_size);
+void rcommonDestroyCmdBuf(radeonContextPtr rmesa);
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h
index 71a4dad58d..4da2479eee 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h
@@ -33,7 +33,7 @@
#define RADEON_CS_LEGACY_H
#include "radeon_cs.h"
-#include "radeon_context.h"
+#include "common_context.h"
struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx);
void radeon_cs_manager_legacy_dtor(struct radeon_cs_manager *csm);
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index c099d0ee34..e655408338 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -47,6 +47,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_macros.h"
#include "radeon_screen.h"
#include "radeon_buffer.h"
+#include "common_misc.h"
#if !RADEON_COMMON
#include "radeon_context.h"
#include "radeon_span.h"