aboutsummaryrefslogtreecommitdiff
path: root/src/wld/nouveau/nouveau.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wld/nouveau/nouveau.c')
-rw-r--r--src/wld/nouveau/nouveau.c941
1 files changed, 441 insertions, 500 deletions
diff --git a/src/wld/nouveau/nouveau.c b/src/wld/nouveau/nouveau.c
index 7d2e364..baed615 100644
--- a/src/wld/nouveau/nouveau.c
+++ b/src/wld/nouveau/nouveau.c
@@ -26,53 +26,49 @@
* SOFTWARE.
*/
+#include "g80_2d.xml.h"
+#include "g80_defs.xml.h"
+#include "nv_object.xml.h"
#include "wld/drm-private.h"
#include "wld/drm.h"
#include "wld/pixman.h"
-#include "nv_object.xml.h"
-#include "g80_2d.xml.h"
-#include "g80_defs.xml.h"
#include <nouveau.h>
#include <sys/mman.h>
-enum nv_architecture
-{
- NV_ARCH_50 = 0x50,
- NV_ARCH_C0 = 0xc0,
- NV_ARCH_E0 = 0xe0
+enum nv_architecture {
+ NV_ARCH_50 = 0x50,
+ NV_ARCH_C0 = 0xc0,
+ NV_ARCH_E0 = 0xe0
};
-struct nouveau_context
-{
- struct wld_context base;
- struct nouveau_device * device;
- struct nouveau_client * client;
- enum nv_architecture architecture;
+struct nouveau_context {
+ struct wld_context base;
+ struct nouveau_device *device;
+ struct nouveau_client *client;
+ enum nv_architecture architecture;
};
-struct nouveau_renderer
-{
- struct wld_renderer base;
- struct nouveau_object * channel;
- struct nouveau_pushbuf * pushbuf;
- struct nouveau_bufctx * bufctx;
- struct nouveau_object * nvc0_2d;
+struct nouveau_renderer {
+ struct wld_renderer base;
+ struct nouveau_object *channel;
+ struct nouveau_pushbuf *pushbuf;
+ struct nouveau_bufctx *bufctx;
+ struct nouveau_object *nvc0_2d;
- struct nouveau_buffer * target;
+ struct nouveau_buffer *target;
};
-struct nouveau_buffer
-{
- struct buffer base;
- struct wld_exporter exporter;
- struct nouveau_context * context;
- struct nouveau_bo * bo;
+struct nouveau_buffer {
+ struct buffer base;
+ struct wld_exporter exporter;
+ struct nouveau_context *context;
+ struct nouveau_bo *bo;
};
+#include "../interface/buffer.h"
#include "../interface/context.h"
#include "../interface/renderer.h"
-#include "../interface/buffer.h"
#define DRM_DRIVER_NAME nouveau
#include "../interface/drm.h"
IMPL(nouveau_context, wld_context)
@@ -80,599 +76,544 @@ IMPL(nouveau_renderer, wld_renderer)
IMPL(nouveau_buffer, wld_buffer)
/**** DRM driver ****/
-bool driver_device_supported(uint32_t vendor_id, uint32_t device_id)
-{
- return vendor_id == 0x10de;
+bool driver_device_supported(uint32_t vendor_id, uint32_t device_id) {
+ return vendor_id == 0x10de;
}
-struct wld_context * driver_create_context(int drm_fd)
-{
- struct nouveau_context * context;
-
- if (!(context = malloc(sizeof *context)))
- goto error0;
-
- if (nouveau_device_wrap(drm_fd, 0, &context->device) != 0)
- goto error1;
-
- switch (context->device->chipset & ~0xf)
- {
- /* TODO: Support NV50
- case 0x50:
- case 0x80:
- case 0x90:
- case 0xa0:
- context->architecture = NV_ARCH_50;
- break;
- */
- case 0xc0:
- case 0xd0:
- context->architecture = NV_ARCH_C0;
- break;
- /* TODO: Support NVE0
- case 0xe0:
- case 0xf0:
- case 0x100:
- context->architecture = NV_ARCH_E0;
- break;
- */
- default:
- return NULL;
- }
+struct wld_context *driver_create_context(int drm_fd) {
+ struct nouveau_context *context;
+
+ if (!(context = malloc(sizeof *context)))
+ goto error0;
+
+ if (nouveau_device_wrap(drm_fd, 0, &context->device) != 0)
+ goto error1;
+
+ switch (context->device->chipset & ~0xf) {
+ /* TODO: Support NV50
+ case 0x50:
+ case 0x80:
+ case 0x90:
+ case 0xa0:
+ context->architecture = NV_ARCH_50;
+ break;
+ */
+ case 0xc0:
+ case 0xd0:
+ context->architecture = NV_ARCH_C0;
+ break;
+ /* TODO: Support NVE0
+ case 0xe0:
+ case 0xf0:
+ case 0x100:
+ context->architecture = NV_ARCH_E0;
+ break;
+ */
+ default:
+ return NULL;
+ }
- if (nouveau_client_new(context->device, &context->client) != 0)
- goto error2;
+ if (nouveau_client_new(context->device, &context->client) != 0)
+ goto error2;
- context_initialize(&context->base, &wld_context_impl);
+ context_initialize(&context->base, &wld_context_impl);
- return &context->base;
+ return &context->base;
- error2:
- nouveau_device_del(&context->device);
- error1:
- free(context);
- error0:
- return NULL;
+error2:
+ nouveau_device_del(&context->device);
+error1:
+ free(context);
+error0:
+ return NULL;
}
/**** Context ****/
-static inline bool ensure_space(struct nouveau_pushbuf * push, uint32_t count)
-{
- if (push->end - push->cur > count)
- return true;
+static inline bool ensure_space(struct nouveau_pushbuf *push, uint32_t count) {
+ if (push->end - push->cur > count)
+ return true;
- return nouveau_pushbuf_space(push, count, 0, 0) == 0;
+ return nouveau_pushbuf_space(push, count, 0, 0) == 0;
}
-static inline void nv_add_dword(struct nouveau_pushbuf * push, uint32_t dword)
-{
- *push->cur++ = dword;
+static inline void nv_add_dword(struct nouveau_pushbuf *push, uint32_t dword) {
+ *push->cur++ = dword;
}
-static inline void nv_add_dwords_va(struct nouveau_pushbuf * push,
- uint16_t count, va_list dwords)
-{
- while (count--)
- nv_add_dword(push, va_arg(dwords, uint32_t));
+static inline void nv_add_dwords_va(struct nouveau_pushbuf *push,
+ uint16_t count, va_list dwords) {
+ while (count--)
+ nv_add_dword(push, va_arg(dwords, uint32_t));
}
-static inline void nv_add_data(struct nouveau_pushbuf * push,
- void * data, uint32_t count)
-{
- memcpy(push->cur, data, count * 4);
- push->cur += count;
+static inline void nv_add_data(struct nouveau_pushbuf *push, void *data,
+ uint32_t count) {
+ memcpy(push->cur, data, count * 4);
+ push->cur += count;
}
-static inline uint32_t nvc0_format(uint32_t format)
-{
- switch (format)
- {
- case WLD_FORMAT_XRGB8888:
- return G80_SURFACE_FORMAT_BGRX8_UNORM;
- case WLD_FORMAT_ARGB8888:
- return G80_SURFACE_FORMAT_BGRA8_UNORM;
- }
+static inline uint32_t nvc0_format(uint32_t format) {
+ switch (format) {
+ case WLD_FORMAT_XRGB8888:
+ return G80_SURFACE_FORMAT_BGRX8_UNORM;
+ case WLD_FORMAT_ARGB8888:
+ return G80_SURFACE_FORMAT_BGRA8_UNORM;
+ }
- return 0;
+ return 0;
}
-enum
-{
- GF100_COMMAND_TYPE_INCREASING = 1,
- GF100_COMMAND_TYPE_NON_INCREASING = 3,
- GF100_COMMAND_TYPE_INLINE = 4
+enum {
+ GF100_COMMAND_TYPE_INCREASING = 1,
+ GF100_COMMAND_TYPE_NON_INCREASING = 3,
+ GF100_COMMAND_TYPE_INLINE = 4
};
-enum
-{
- GF100_SUBCHANNEL_2D = 3,
+enum {
+ GF100_SUBCHANNEL_2D = 3,
};
static inline uint32_t nvc0_command(uint8_t type, uint8_t subchannel,
- uint16_t method, uint16_t count_or_value)
-{
- return type << 29 | count_or_value << 16 | subchannel << 13 | method >> 2;
+ uint16_t method, uint16_t count_or_value) {
+ return type << 29 | count_or_value << 16 | subchannel << 13 | method >> 2;
}
-static inline void nvc0_inline(struct nouveau_pushbuf * push,
- uint8_t subchannel, uint16_t method,
- uint16_t value)
-{
- nv_add_dword(push, nvc0_command(GF100_COMMAND_TYPE_INLINE,
- subchannel, method, value));
+static inline void nvc0_inline(struct nouveau_pushbuf *push, uint8_t subchannel,
+ uint16_t method, uint16_t value) {
+ nv_add_dword(
+ push, nvc0_command(GF100_COMMAND_TYPE_INLINE, subchannel, method, value));
}
-static inline void nvc0_methods(struct nouveau_pushbuf * push,
+static inline void nvc0_methods(struct nouveau_pushbuf *push,
uint8_t subchannel, uint16_t start_method,
- uint16_t count, ...)
-{
- va_list dwords;
- nv_add_dword(push, nvc0_command(GF100_COMMAND_TYPE_INCREASING,
- subchannel, start_method, count));
- va_start(dwords, count);
- nv_add_dwords_va(push, count, dwords);
- va_end(dwords);
+ uint16_t count, ...) {
+ va_list dwords;
+ nv_add_dword(push, nvc0_command(GF100_COMMAND_TYPE_INCREASING, subchannel,
+ start_method, count));
+ va_start(dwords, count);
+ nv_add_dwords_va(push, count, dwords);
+ va_end(dwords);
}
-#define nvc0_2d(push, method, count, ...) \
- nvc0_methods(push, GF100_SUBCHANNEL_2D, method, count, __VA_ARGS__)
-#define nvc0_2d_inline(push, method, value) \
- nvc0_inline(push, GF100_SUBCHANNEL_2D, method, value)
+#define nvc0_2d(push, method, count, ...) \
+ nvc0_methods(push, GF100_SUBCHANNEL_2D, method, count, __VA_ARGS__)
+#define nvc0_2d_inline(push, method, value) \
+ nvc0_inline(push, GF100_SUBCHANNEL_2D, method, value)
-static bool nvc0_2d_initialize(struct nouveau_renderer * renderer)
-{
- int ret;
+static bool nvc0_2d_initialize(struct nouveau_renderer *renderer) {
+ int ret;
- ret = nouveau_object_new(renderer->channel, GF100_2D, GF100_2D, NULL, 0,
- &renderer->nvc0_2d);
+ ret = nouveau_object_new(renderer->channel, GF100_2D, GF100_2D, NULL, 0,
+ &renderer->nvc0_2d);
- if (ret != 0)
- goto error0;
+ if (ret != 0)
+ goto error0;
- if (!ensure_space(renderer->pushbuf, 5))
- goto error1;
+ if (!ensure_space(renderer->pushbuf, 5))
+ goto error1;
- nvc0_2d(renderer->pushbuf, NV1_SUBCHAN_OBJECT, 1,
- renderer->nvc0_2d->handle);
- nvc0_2d_inline(renderer->pushbuf, G80_2D_OPERATION,
- G80_2D_OPERATION_SRCCOPY_AND);
- nvc0_2d_inline(renderer->pushbuf, G80_2D_UNK0884, 0x3f);
- nvc0_2d_inline(renderer->pushbuf, G80_2D_UNK0888, 1);
+ nvc0_2d(renderer->pushbuf, NV1_SUBCHAN_OBJECT, 1, renderer->nvc0_2d->handle);
+ nvc0_2d_inline(renderer->pushbuf, G80_2D_OPERATION,
+ G80_2D_OPERATION_SRCCOPY_AND);
+ nvc0_2d_inline(renderer->pushbuf, G80_2D_UNK0884, 0x3f);
+ nvc0_2d_inline(renderer->pushbuf, G80_2D_UNK0888, 1);
- return true;
+ return true;
- error1:
- nouveau_object_del(&renderer->nvc0_2d);
- error0:
- return false;
+error1:
+ nouveau_object_del(&renderer->nvc0_2d);
+error0:
+ return false;
}
-static void nvc0_2d_finalize(struct nouveau_renderer * renderer)
-{
- nouveau_object_del(&renderer->nvc0_2d);
+static void nvc0_2d_finalize(struct nouveau_renderer *renderer) {
+ nouveau_object_del(&renderer->nvc0_2d);
}
-struct wld_renderer * context_create_renderer(struct wld_context * base)
-{
- struct nouveau_context * context = nouveau_context(base);
- struct nouveau_renderer * renderer;
- struct nvc0_fifo fifo = { };
- int ret;
+struct wld_renderer *context_create_renderer(struct wld_context *base) {
+ struct nouveau_context *context = nouveau_context(base);
+ struct nouveau_renderer *renderer;
+ struct nvc0_fifo fifo = {};
+ int ret;
- if (!(renderer = malloc(sizeof *renderer)))
- goto error0;
+ if (!(renderer = malloc(sizeof *renderer)))
+ goto error0;
- ret = nouveau_object_new(&context->device->object, 0,
- NOUVEAU_FIFO_CHANNEL_CLASS, &fifo, sizeof fifo,
- &renderer->channel);
+ ret = nouveau_object_new(&context->device->object, 0,
+ NOUVEAU_FIFO_CHANNEL_CLASS, &fifo, sizeof fifo,
+ &renderer->channel);
- if (ret != 0)
- goto error1;
+ if (ret != 0)
+ goto error1;
- ret = nouveau_pushbuf_new(context->client, renderer->channel, 4, 32 * 1024,
- true, &renderer->pushbuf);
+ ret = nouveau_pushbuf_new(context->client, renderer->channel, 4, 32 * 1024,
+ true, &renderer->pushbuf);
- if (ret != 0)
- goto error2;
+ if (ret != 0)
+ goto error2;
- if (nouveau_bufctx_new(context->client, 1, &renderer->bufctx) != 0)
- goto error3;
+ if (nouveau_bufctx_new(context->client, 1, &renderer->bufctx) != 0)
+ goto error3;
- if (!nvc0_2d_initialize(renderer))
- goto error4;
+ if (!nvc0_2d_initialize(renderer))
+ goto error4;
- renderer_initialize(&renderer->base, &wld_renderer_impl);
- renderer->target = NULL;
+ renderer_initialize(&renderer->base, &wld_renderer_impl);
+ renderer->target = NULL;
- return &renderer->base;
+ return &renderer->base;
- error4:
- nouveau_bufctx_del(&renderer->bufctx);
- error3:
- nouveau_pushbuf_del(&renderer->pushbuf);
- error2:
- nouveau_object_del(&renderer->channel);
- error1:
- free(renderer);
- error0:
- return NULL;
+error4:
+ nouveau_bufctx_del(&renderer->bufctx);
+error3:
+ nouveau_pushbuf_del(&renderer->pushbuf);
+error2:
+ nouveau_object_del(&renderer->channel);
+error1:
+ free(renderer);
+error0:
+ return NULL;
}
-static bool export(struct wld_exporter * exporter, struct wld_buffer * base,
- uint32_t type, union wld_object * object)
-{
- struct nouveau_buffer * buffer = nouveau_buffer(base);
-
- switch (type)
- {
- case WLD_DRM_OBJECT_HANDLE:
- object->u32 = buffer->bo->handle;
- return true;
- case WLD_DRM_OBJECT_PRIME_FD:
- if (nouveau_bo_set_prime(buffer->bo, &object->i) != 0)
- return false;
- return true;
- default:
- return false;
- }
+static bool export(struct wld_exporter *exporter, struct wld_buffer *base,
+ uint32_t type, union wld_object *object) {
+ struct nouveau_buffer *buffer = nouveau_buffer(base);
+
+ switch (type) {
+ case WLD_DRM_OBJECT_HANDLE:
+ object->u32 = buffer->bo->handle;
+ return true;
+ case WLD_DRM_OBJECT_PRIME_FD:
+ if (nouveau_bo_set_prime(buffer->bo, &object->i) != 0)
+ return false;
+ return true;
+ default:
+ return false;
+ }
}
-static struct nouveau_buffer * new_buffer(struct nouveau_context * context,
- uint32_t width, uint32_t height,
- uint32_t format, uint32_t pitch)
-{
- struct nouveau_buffer * buffer;
+static struct nouveau_buffer *new_buffer(struct nouveau_context *context,
+ uint32_t width, uint32_t height,
+ uint32_t format, uint32_t pitch) {
+ struct nouveau_buffer *buffer;
- if (!(buffer = malloc(sizeof *buffer)))
- return NULL;
+ if (!(buffer = malloc(sizeof *buffer)))
+ return NULL;
- buffer_initialize(&buffer->base, &wld_buffer_impl,
- width, height, format, pitch);
- buffer->context = context;
- buffer->exporter.export = &export;
- wld_buffer_add_exporter(&buffer->base.base, &buffer->exporter);
+ buffer_initialize(&buffer->base, &wld_buffer_impl, width, height, format,
+ pitch);
+ buffer->context = context;
+ buffer->exporter.export = &export;
+ wld_buffer_add_exporter(&buffer->base.base, &buffer->exporter);
- return buffer;
+ return buffer;
}
-static inline uint32_t roundup(uint32_t value, uint32_t alignment)
-{
- return (value + alignment - 1) & ~(alignment - 1);
+static inline uint32_t roundup(uint32_t value, uint32_t alignment) {
+ return (value + alignment - 1) & ~(alignment - 1);
}
-struct buffer * context_create_buffer(struct wld_context * base,
- uint32_t width, uint32_t height,
- uint32_t format, uint32_t flags)
-{
- struct nouveau_context * context = nouveau_context(base);
- struct nouveau_buffer * buffer;
- uint32_t bpp = format_bytes_per_pixel(format),
- pitch = roundup(width * bpp, 64), bo_flags;
- union nouveau_bo_config config = { };
-
- if (!(buffer = new_buffer(context, width, height, format, pitch)))
- goto error0;
-
- bo_flags = NOUVEAU_BO_VRAM;
-
- if (flags & WLD_DRM_FLAG_SCANOUT)
- bo_flags |= NOUVEAU_BO_CONTIG;
-
- if (height > 0x40 && !(flags & WLD_FLAG_MAP))
- {
- config.nvc0.tile_mode = 0x40;
- config.nvc0.memtype = 0xfe;
- height = roundup(height, 0x80);
- }
- else
- bo_flags |= NOUVEAU_BO_MAP;
-
- if (nouveau_bo_new(context->device, bo_flags, 0, pitch * height,
- &config, &buffer->bo) != 0)
- {
- goto error1;
- }
-
- return &buffer->base;
-
- error1:
- free(buffer);
- error0:
- return NULL;
+struct buffer *context_create_buffer(struct wld_context *base, uint32_t width,
+ uint32_t height, uint32_t format,
+ uint32_t flags) {
+ struct nouveau_context *context = nouveau_context(base);
+ struct nouveau_buffer *buffer;
+ uint32_t bpp = format_bytes_per_pixel(format),
+ pitch = roundup(width * bpp, 64), bo_flags;
+ union nouveau_bo_config config = {};
+
+ if (!(buffer = new_buffer(context, width, height, format, pitch)))
+ goto error0;
+
+ bo_flags = NOUVEAU_BO_VRAM;
+
+ if (flags & WLD_DRM_FLAG_SCANOUT)
+ bo_flags |= NOUVEAU_BO_CONTIG;
+
+ if (height > 0x40 && !(flags & WLD_FLAG_MAP)) {
+ config.nvc0.tile_mode = 0x40;
+ config.nvc0.memtype = 0xfe;
+ height = roundup(height, 0x80);
+ } else
+ bo_flags |= NOUVEAU_BO_MAP;
+
+ if (nouveau_bo_new(context->device, bo_flags, 0, pitch * height, &config,
+ &buffer->bo) != 0) {
+ goto error1;
+ }
+
+ return &buffer->base;
+
+error1:
+ free(buffer);
+error0:
+ return NULL;
}
-struct buffer * context_import_buffer(struct wld_context * base,
- uint32_t type, union wld_object object,
- uint32_t width, uint32_t height,
- uint32_t format, uint32_t pitch)
-{
- struct nouveau_context * context = (void *) base;
- struct nouveau_buffer * buffer;
- struct nouveau_bo * bo = NULL;
-
- switch (type)
- {
- case WLD_DRM_OBJECT_PRIME_FD:
- if (nouveau_bo_prime_handle_ref(context->device,
- object.i, &bo) != 0)
- {
- goto error0;
- }
- break;
- default: goto error0;
+struct buffer *context_import_buffer(struct wld_context *base, uint32_t type,
+ union wld_object object, uint32_t width,
+ uint32_t height, uint32_t format,
+ uint32_t pitch) {
+ struct nouveau_context *context = (void *)base;
+ struct nouveau_buffer *buffer;
+ struct nouveau_bo *bo = NULL;
+
+ switch (type) {
+ case WLD_DRM_OBJECT_PRIME_FD:
+ if (nouveau_bo_prime_handle_ref(context->device, object.i, &bo) != 0) {
+ goto error0;
}
+ break;
+ default:
+ goto error0;
+ }
- if (!(buffer = new_buffer(context, width, height, format, pitch)))
- goto error1;
+ if (!(buffer = new_buffer(context, width, height, format, pitch)))
+ goto error1;
- buffer->bo = bo;
+ buffer->bo = bo;
- return &buffer->base;
+ return &buffer->base;
- error1:
- nouveau_bo_ref(NULL, &buffer->bo);
- error0:
- return NULL;
+error1:
+ nouveau_bo_ref(NULL, &buffer->bo);
+error0:
+ return NULL;
}
-void context_destroy(struct wld_context * base)
-{
- struct nouveau_context * context = nouveau_context(base);
+void context_destroy(struct wld_context *base) {
+ struct nouveau_context *context = nouveau_context(base);
- nouveau_client_del(&context->client);
- nouveau_device_del(&context->device);
- free(context);
+ nouveau_client_del(&context->client);
+ nouveau_device_del(&context->device);
+ free(context);
}
/**** Renderer ****/
-uint32_t renderer_capabilities(struct wld_renderer * renderer,
- struct buffer * buffer)
-{
- if (buffer->base.impl == &wld_buffer_impl)
- return WLD_CAPABILITY_READ | WLD_CAPABILITY_WRITE;
+uint32_t renderer_capabilities(struct wld_renderer *renderer,
+ struct buffer *buffer) {
+ if (buffer->base.impl == &wld_buffer_impl)
+ return WLD_CAPABILITY_READ | WLD_CAPABILITY_WRITE;
- return 0;
+ return 0;
}
-bool renderer_set_target(struct wld_renderer * base, struct buffer * buffer)
-{
- struct nouveau_renderer * renderer = nouveau_renderer(base);
+bool renderer_set_target(struct wld_renderer *base, struct buffer *buffer) {
+ struct nouveau_renderer *renderer = nouveau_renderer(base);
- if (buffer && buffer->base.impl != &wld_buffer_impl)
- return false;
+ if (buffer && buffer->base.impl != &wld_buffer_impl)
+ return false;
- renderer->target = buffer ? nouveau_buffer(&buffer->base) : NULL;
+ renderer->target = buffer ? nouveau_buffer(&buffer->base) : NULL;
- return true;
+ return true;
}
-static inline void nvc0_2d_use_buffer(struct nouveau_renderer * renderer,
- struct nouveau_buffer * buffer,
- uint16_t format_method, uint16_t format)
-{
- uint32_t access = format == G80_2D_SRC_FORMAT ? NOUVEAU_BO_RD
- : NOUVEAU_BO_WR;
-
- nvc0_2d_inline(renderer->pushbuf, format_method, format);
-
- if (buffer->bo->config.nvc0.memtype)
- {
- nvc0_2d(renderer->pushbuf, format_method + 0x04, 2,
- 0, buffer->bo->config.nvc0.tile_mode);
- }
- else
- {
- nvc0_2d_inline(renderer->pushbuf, format_method + 0x04, 1);
- nvc0_2d(renderer->pushbuf, format_method + 0x14, 1,
- buffer->base.base.pitch);
- }
-
- nvc0_2d(renderer->pushbuf, format_method + 0x18, 4,
- buffer->base.base.width, buffer->base.base.height,
- buffer->bo->offset >> 32, buffer->bo->offset);
- nouveau_bufctx_refn(renderer->bufctx, 0, buffer->bo,
- NOUVEAU_BO_VRAM | access);
+static inline void nvc0_2d_use_buffer(struct nouveau_renderer *renderer,
+ struct nouveau_buffer *buffer,
+ uint16_t format_method, uint16_t format) {
+ uint32_t access = format == G80_2D_SRC_FORMAT ? NOUVEAU_BO_RD : NOUVEAU_BO_WR;
+
+ nvc0_2d_inline(renderer->pushbuf, format_method, format);
+
+ if (buffer->bo->config.nvc0.memtype) {
+ nvc0_2d(renderer->pushbuf, format_method + 0x04, 2, 0,
+ buffer->bo->config.nvc0.tile_mode);
+ } else {
+ nvc0_2d_inline(renderer->pushbuf, format_method + 0x04, 1);
+ nvc0_2d(renderer->pushbuf, format_method + 0x14, 1,
+ buffer->base.base.pitch);
+ }
+
+ nvc0_2d(renderer->pushbuf, format_method + 0x18, 4, buffer->base.base.width,
+ buffer->base.base.height, buffer->bo->offset >> 32,
+ buffer->bo->offset);
+ nouveau_bufctx_refn(renderer->bufctx, 0, buffer->bo,
+ NOUVEAU_BO_VRAM | access);
}
-void renderer_fill_rectangle(struct wld_renderer * base, uint32_t color,
- int32_t x, int32_t y,
- uint32_t width, uint32_t height)
-{
- struct nouveau_renderer * renderer = nouveau_renderer(base);
- struct nouveau_buffer * dst = renderer->target;
- uint32_t format;
+void renderer_fill_rectangle(struct wld_renderer *base, uint32_t color,
+ int32_t x, int32_t y, uint32_t width,
+ uint32_t height) {
+ struct nouveau_renderer *renderer = nouveau_renderer(base);
+ struct nouveau_buffer *dst = renderer->target;
+ uint32_t format;
- if (!ensure_space(renderer->pushbuf, 18))
- return;
+ if (!ensure_space(renderer->pushbuf, 18))
+ return;
- format = nvc0_format(dst->base.base.format);
+ format = nvc0_format(dst->base.base.format);
- nouveau_bufctx_reset(renderer->bufctx, 0);
- nvc0_2d_use_buffer(renderer, dst, G80_2D_DST_FORMAT, format);
- nvc0_2d(renderer->pushbuf, G80_2D_DRAW_SHAPE, 3,
- G80_2D_DRAW_SHAPE_RECTANGLES, format, color);
- nouveau_pushbuf_bufctx(renderer->pushbuf, renderer->bufctx);
+ nouveau_bufctx_reset(renderer->bufctx, 0);
+ nvc0_2d_use_buffer(renderer, dst, G80_2D_DST_FORMAT, format);
+ nvc0_2d(renderer->pushbuf, G80_2D_DRAW_SHAPE, 3, G80_2D_DRAW_SHAPE_RECTANGLES,
+ format, color);
+ nouveau_pushbuf_bufctx(renderer->pushbuf, renderer->bufctx);
- if (nouveau_pushbuf_validate(renderer->pushbuf) != 0)
- return;
+ if (nouveau_pushbuf_validate(renderer->pushbuf) != 0)
+ return;
- nvc0_2d(renderer->pushbuf, G80_2D_DRAW_POINT32_X(0), 4,
- x, y, x + width, y + height);
+ nvc0_2d(renderer->pushbuf, G80_2D_DRAW_POINT32_X(0), 4, x, y, x + width,
+ y + height);
}
-void renderer_copy_rectangle(struct wld_renderer * base,
- struct buffer * buffer_base,
- int32_t dst_x, int32_t dst_y,
- int32_t src_x, int32_t src_y,
- uint32_t width, uint32_t height)
-{
- struct nouveau_renderer * renderer = nouveau_renderer(base);
+void renderer_copy_rectangle(struct wld_renderer *base,
+ struct buffer *buffer_base, int32_t dst_x,
+ int32_t dst_y, int32_t src_x, int32_t src_y,
+ uint32_t width, uint32_t height) {
+ struct nouveau_renderer *renderer = nouveau_renderer(base);
- if (buffer_base->base.impl != &wld_buffer_impl)
- return;
+ if (buffer_base->base.impl != &wld_buffer_impl)
+ return;
- struct nouveau_buffer * src = nouveau_buffer(&buffer_base->base),
- * dst = renderer->target;
- uint32_t src_format, dst_format;
+ struct nouveau_buffer *src = nouveau_buffer(&buffer_base->base),
+ *dst = renderer->target;
+ uint32_t src_format, dst_format;
- if (!ensure_space(renderer->pushbuf, 33))
- return;
+ if (!ensure_space(renderer->pushbuf, 33))
+ return;
- src_format = nvc0_format(src->base.base.format);
- dst_format = nvc0_format(dst->base.base.format);
+ src_format = nvc0_format(src->base.base.format);
+ dst_format = nvc0_format(dst->base.base.format);
- nouveau_bufctx_reset(renderer->bufctx, 0);
- nvc0_2d_use_buffer(renderer, src, G80_2D_SRC_FORMAT, src_format);
- nvc0_2d_use_buffer(renderer, dst, G80_2D_DST_FORMAT, dst_format);
- nouveau_pushbuf_bufctx(renderer->pushbuf, renderer->bufctx);
+ nouveau_bufctx_reset(renderer->bufctx, 0);
+ nvc0_2d_use_buffer(renderer, src, G80_2D_SRC_FORMAT, src_format);
+ nvc0_2d_use_buffer(renderer, dst, G80_2D_DST_FORMAT, dst_format);
+ nouveau_pushbuf_bufctx(renderer->pushbuf, renderer->bufctx);
- if (nouveau_pushbuf_validate(renderer->pushbuf) != 0)
- return;
+ if (nouveau_pushbuf_validate(renderer->pushbuf) != 0)
+ return;
- nvc0_2d_inline(renderer->pushbuf, G80_GRAPH_SERIALIZE, 0);
- nvc0_2d_inline(renderer->pushbuf, G80_2D_BLIT_CONTROL,
- G80_2D_BLIT_CONTROL_ORIGIN_CENTER
- | G80_2D_BLIT_CONTROL_FILTER_POINT_SAMPLE);
- nvc0_2d(renderer->pushbuf, G80_2D_BLIT_DST_X, 12,
- dst_x, dst_y, width, height, 0, 1, 0, 1, 0, src_x, 0, src_y);
+ nvc0_2d_inline(renderer->pushbuf, G80_GRAPH_SERIALIZE, 0);
+ nvc0_2d_inline(renderer->pushbuf, G80_2D_BLIT_CONTROL,
+ G80_2D_BLIT_CONTROL_ORIGIN_CENTER |
+ G80_2D_BLIT_CONTROL_FILTER_POINT_SAMPLE);
+ nvc0_2d(renderer->pushbuf, G80_2D_BLIT_DST_X, 12, dst_x, dst_y, width, height,
+ 0, 1, 0, 1, 0, src_x, 0, src_y);
- renderer_flush(base);
+ renderer_flush(base);
}
-void renderer_draw_text(struct wld_renderer * base,
- struct font * font, uint32_t color,
- int32_t x, int32_t y, const char * text,
- uint32_t length, struct wld_extents * extents)
-{
- struct nouveau_renderer * renderer = nouveau_renderer(base);
- struct nouveau_buffer * dst = renderer->target;
- uint32_t format;
- int ret;
- struct glyph * glyph;
- FT_UInt glyph_index;
- uint32_t c, count;
- int32_t origin_x = x;
-
- if (!ensure_space(renderer->pushbuf, 17))
- return;
-
- format = nvc0_format(dst->base.base.format);
-
- nouveau_bufctx_reset(renderer->bufctx, 0);
- nvc0_2d_use_buffer(renderer, dst, G80_2D_DST_FORMAT, format);
- nvc0_2d_inline(renderer->pushbuf, G80_2D_SIFC_BITMAP_ENABLE, 1);
- nvc0_2d(renderer->pushbuf, G80_2D_SIFC_BITMAP_FORMAT, 6,
- G80_2D_SIFC_BITMAP_FORMAT_I1,
- 0, /* SIFC_FORMAT */
- G80_2D_SIFC_BITMAP_LINE_PACK_MODE_ALIGN_BYTE,
- 0, color, /* SIFC_BITMAP_COLOR_BIT0, SIFC_BITMAP_COLOR_BIT1 */
- 0 /* SIFC_BITMAP_WRITE_BIT0_ENABLE */
- );
- nouveau_pushbuf_bufctx(renderer->pushbuf, renderer->bufctx);
-
- if (nouveau_pushbuf_validate(renderer->pushbuf) != 0)
- return;
-
- if (length == -1)
- length = strlen(text);
-
- while ((ret = FcUtf8ToUcs4((FcChar8 *) text, &c, length)) > 0 && c != '\0')
- {
- text += ret;
- length -= ret;
- glyph_index = FT_Get_Char_Index(font->face, c);
-
- if (!font_ensure_glyph(font, glyph_index))
- continue;
-
- glyph = font->glyphs[glyph_index];
-
- if (glyph->bitmap.width == 0 || glyph->bitmap.rows == 0)
- goto advance;
-
- count = (glyph->bitmap.pitch * glyph->bitmap.rows + 3) / 4;
-
- if (!ensure_space(renderer->pushbuf, 12 + count))
- return;
-
- nvc0_2d(renderer->pushbuf, G80_2D_SIFC_WIDTH, 10,
- /* Use the pitch instead of width to ensure the correct
- * alignment is used. */
- glyph->bitmap.pitch * 8, glyph->bitmap.rows,
- 0, 1, 0, 1,
- 0, origin_x + glyph->x, 0, y + glyph->y);
- nv_add_dword(renderer->pushbuf,
- nvc0_command(GF100_COMMAND_TYPE_NON_INCREASING,
- GF100_SUBCHANNEL_2D,
- G80_2D_SIFC_DATA, count));
- nv_add_data(renderer->pushbuf, glyph->bitmap.buffer, count);
-
- advance:
- origin_x += glyph->advance;
- }
-
- if (extents)
- extents->advance = origin_x - x;
+void renderer_draw_text(struct wld_renderer *base, struct font *font,
+ uint32_t color, int32_t x, int32_t y, const char *text,
+ uint32_t length, struct wld_extents *extents) {
+ struct nouveau_renderer *renderer = nouveau_renderer(base);
+ struct nouveau_buffer *dst = renderer->target;
+ uint32_t format;
+ int ret;
+ struct glyph *glyph;
+ FT_UInt glyph_index;
+ uint32_t c, count;
+ int32_t origin_x = x;
+
+ if (!ensure_space(renderer->pushbuf, 17))
+ return;
+
+ format = nvc0_format(dst->base.base.format);
+
+ nouveau_bufctx_reset(renderer->bufctx, 0);
+ nvc0_2d_use_buffer(renderer, dst, G80_2D_DST_FORMAT, format);
+ nvc0_2d_inline(renderer->pushbuf, G80_2D_SIFC_BITMAP_ENABLE, 1);
+ nvc0_2d(renderer->pushbuf, G80_2D_SIFC_BITMAP_FORMAT, 6,
+ G80_2D_SIFC_BITMAP_FORMAT_I1, 0, /* SIFC_FORMAT */
+ G80_2D_SIFC_BITMAP_LINE_PACK_MODE_ALIGN_BYTE, 0,
+ color, /* SIFC_BITMAP_COLOR_BIT0, SIFC_BITMAP_COLOR_BIT1 */
+ 0 /* SIFC_BITMAP_WRITE_BIT0_ENABLE */
+ );
+ nouveau_pushbuf_bufctx(renderer->pushbuf, renderer->bufctx);
+
+ if (nouveau_pushbuf_validate(renderer->pushbuf) != 0)
+ return;
+
+ if (length == -1)
+ length = strlen(text);
+
+ while ((ret = FcUtf8ToUcs4((FcChar8 *)text, &c, length)) > 0 && c != '\0') {
+ text += ret;
+ length -= ret;
+ glyph_index = FT_Get_Char_Index(font->face, c);
+
+ if (!font_ensure_glyph(font, glyph_index))
+ continue;
+
+ glyph = font->glyphs[glyph_index];
+
+ if (glyph->bitmap.width == 0 || glyph->bitmap.rows == 0)
+ goto advance;
+
+ count = (glyph->bitmap.pitch * glyph->bitmap.rows + 3) / 4;
+
+ if (!ensure_space(renderer->pushbuf, 12 + count))
+ return;
+
+ nvc0_2d(renderer->pushbuf, G80_2D_SIFC_WIDTH, 10,
+ /* Use the pitch instead of width to ensure the correct
+ * alignment is used. */
+ glyph->bitmap.pitch * 8, glyph->bitmap.rows, 0, 1, 0, 1, 0,
+ origin_x + glyph->x, 0, y + glyph->y);
+ nv_add_dword(renderer->pushbuf,
+ nvc0_command(GF100_COMMAND_TYPE_NON_INCREASING,
+ GF100_SUBCHANNEL_2D, G80_2D_SIFC_DATA, count));
+ nv_add_data(renderer->pushbuf, glyph->bitmap.buffer, count);
+
+ advance:
+ origin_x += glyph->advance;
+ }
+
+ if (extents)
+ extents->advance = origin_x - x;
}
-void renderer_flush(struct wld_renderer * base)
-{
- struct nouveau_renderer * renderer = nouveau_renderer(base);
+void renderer_flush(struct wld_renderer *base) {
+ struct nouveau_renderer *renderer = nouveau_renderer(base);
- nouveau_pushbuf_kick(renderer->pushbuf, renderer->channel);
- nouveau_pushbuf_bufctx(renderer->pushbuf, NULL);
+ nouveau_pushbuf_kick(renderer->pushbuf, renderer->channel);
+ nouveau_pushbuf_bufctx(renderer->pushbuf, NULL);
}
-void renderer_destroy(struct wld_renderer * base)
-{
- struct nouveau_renderer * renderer = nouveau_renderer(base);
+void renderer_destroy(struct wld_renderer *base) {
+ struct nouveau_renderer *renderer = nouveau_renderer(base);
- nvc0_2d_finalize(renderer);
- nouveau_bufctx_del(&renderer->bufctx);
- nouveau_pushbuf_del(&renderer->pushbuf);
- nouveau_object_del(&renderer->channel);
- free(renderer);
+ nvc0_2d_finalize(renderer);
+ nouveau_bufctx_del(&renderer->bufctx);
+ nouveau_pushbuf_del(&renderer->pushbuf);
+ nouveau_object_del(&renderer->channel);
+ free(renderer);
}
/**** Buffer ****/
-bool buffer_map(struct buffer * base)
-{
- struct nouveau_buffer * buffer = nouveau_buffer(&base->base);
-
- /* If the buffer is tiled, it cannot be mapped into virtual memory in order
- * to appear linear like intel can do with map_gtt. */
- if (buffer->bo->config.nvc0.tile_mode)
- return false;
-
- if (nouveau_bo_map(buffer->bo, NOUVEAU_BO_WR,
- buffer->context->client) != 0)
- {
- return false;
- }
+bool buffer_map(struct buffer *base) {
+ struct nouveau_buffer *buffer = nouveau_buffer(&base->base);
- buffer->base.base.map = buffer->bo->map;
+ /* If the buffer is tiled, it cannot be mapped into virtual memory in order
+ * to appear linear like intel can do with map_gtt. */
+ if (buffer->bo->config.nvc0.tile_mode)
+ return false;
- return true;
+ if (nouveau_bo_map(buffer->bo, NOUVEAU_BO_WR, buffer->context->client) != 0) {
+ return false;
+ }
+
+ buffer->base.base.map = buffer->bo->map;
+
+ return true;
}
-bool buffer_unmap(struct buffer * base)
-{
- struct nouveau_buffer * buffer = nouveau_buffer(&base->base);
+bool buffer_unmap(struct buffer *base) {
+ struct nouveau_buffer *buffer = nouveau_buffer(&base->base);
- if (munmap(buffer->bo->map, buffer->bo->size) == -1)
- return false;
+ if (munmap(buffer->bo->map, buffer->bo->size) == -1)
+ return false;
- buffer->bo->map = NULL;
- base->base.map = NULL;
+ buffer->bo->map = NULL;
+ base->base.map = NULL;
- return true;
+ return true;
}
-void buffer_destroy(struct buffer * base)
-{
- struct nouveau_buffer * buffer = nouveau_buffer(&base->base);
+void buffer_destroy(struct buffer *base) {
+ struct nouveau_buffer *buffer = nouveau_buffer(&base->base);
- nouveau_bo_ref(NULL, &buffer->bo);
- free(buffer);
+ nouveau_bo_ref(NULL, &buffer->bo);
+ free(buffer);
}
-