mirror of
https://gitee.com/openharmony/third_party_mesa3d
synced 2024-11-23 07:19:50 +00:00
gallium: Learn about kopper
Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14541>
This commit is contained in:
parent
bab8d97ea9
commit
d760a9151b
@ -667,6 +667,32 @@ trace_screen_resource_create(struct pipe_screen *_screen,
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct pipe_resource *
|
||||
trace_screen_resource_create_drawable(struct pipe_screen *_screen,
|
||||
const struct pipe_resource *templat,
|
||||
const void *loader_data)
|
||||
{
|
||||
struct trace_screen *tr_scr = trace_screen(_screen);
|
||||
struct pipe_screen *screen = tr_scr->screen;
|
||||
struct pipe_resource *result;
|
||||
|
||||
trace_dump_call_begin("pipe_screen", "resource_create_drawable");
|
||||
|
||||
trace_dump_arg(ptr, screen);
|
||||
trace_dump_arg(resource_template, templat);
|
||||
trace_dump_arg(ptr, loader_data);
|
||||
|
||||
result = screen->resource_create_drawable(screen, templat, loader_data);
|
||||
|
||||
trace_dump_ret(ptr, result);
|
||||
|
||||
trace_dump_call_end();
|
||||
|
||||
if (result)
|
||||
result->screen = _screen;
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct pipe_resource *
|
||||
trace_screen_resource_create_with_modifiers(struct pipe_screen *_screen, const struct pipe_resource *templat,
|
||||
const uint64_t *modifiers, int modifiers_count)
|
||||
@ -1283,6 +1309,7 @@ trace_screen_create(struct pipe_screen *screen)
|
||||
tr_scr->base.resource_create = trace_screen_resource_create;
|
||||
SCR_INIT(resource_create_with_modifiers);
|
||||
tr_scr->base.resource_create_unbacked = trace_screen_resource_create_unbacked;
|
||||
SCR_INIT(resource_create_drawable);
|
||||
tr_scr->base.resource_bind_backing = trace_screen_resource_bind_backing;
|
||||
tr_scr->base.resource_from_handle = trace_screen_resource_from_handle;
|
||||
tr_scr->base.allocate_memory = trace_screen_allocate_memory;
|
||||
@ -1345,3 +1372,12 @@ trace_screen(struct pipe_screen *screen)
|
||||
assert(screen->destroy == trace_screen_destroy);
|
||||
return (struct trace_screen *)screen;
|
||||
}
|
||||
|
||||
struct pipe_screen *
|
||||
trace_screen_unwrap(struct pipe_screen *_screen)
|
||||
{
|
||||
if (_screen->destroy != trace_screen_destroy)
|
||||
return _screen;
|
||||
struct trace_screen *tr_scr = trace_screen(_screen);
|
||||
return tr_scr->screen;
|
||||
}
|
||||
|
@ -59,6 +59,8 @@ struct trace_screen
|
||||
struct trace_screen *
|
||||
trace_screen(struct pipe_screen *screen);
|
||||
|
||||
struct pipe_screen *
|
||||
trace_screen_unwrap(struct pipe_screen *_screen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ libpipe_loader_static = static_library(
|
||||
files_pipe_loader,
|
||||
include_directories : [
|
||||
inc_util, inc_loader, inc_gallium, inc_include, inc_src, inc_gallium_aux,
|
||||
inc_gallium_winsys,
|
||||
inc_gallium_winsys, inc_gallium_drivers,
|
||||
],
|
||||
c_args : [libpipe_loader_defines, '-DGALLIUM_STATIC_TARGETS=1'],
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
@ -59,7 +59,7 @@ libpipe_loader_dynamic = static_library(
|
||||
files_pipe_loader,
|
||||
include_directories : [
|
||||
inc_util, inc_loader, inc_gallium, inc_include, inc_src, inc_gallium_aux,
|
||||
inc_gallium_winsys,
|
||||
inc_gallium_winsys, inc_gallium_drivers,
|
||||
],
|
||||
c_args : [
|
||||
libpipe_loader_defines,
|
||||
|
@ -143,6 +143,20 @@ bool
|
||||
pipe_loader_sw_probe_dri(struct pipe_loader_device **devs,
|
||||
const struct drisw_loader_funcs *drisw_lf);
|
||||
|
||||
/**
|
||||
* Initialize vk dri device give the drisw_loader_funcs.
|
||||
*
|
||||
* This function is platform-specific.
|
||||
*
|
||||
* Function does not take ownership of the fd, but duplicates it locally.
|
||||
* The local fd is closed during pipe_loader_release.
|
||||
*
|
||||
* \sa pipe_loader_probe
|
||||
*/
|
||||
bool
|
||||
pipe_loader_vk_probe_dri(struct pipe_loader_device **devs,
|
||||
const struct drisw_loader_funcs *drisw_lf);
|
||||
|
||||
/**
|
||||
* Initialize a kms backed sw device given an fd.
|
||||
*
|
||||
|
@ -43,7 +43,7 @@
|
||||
#include "frontend/drisw_api.h"
|
||||
#include "frontend/sw_driver.h"
|
||||
#include "frontend/sw_winsys.h"
|
||||
|
||||
#include "util/driconf.h"
|
||||
|
||||
struct pipe_loader_sw_device {
|
||||
struct pipe_loader_device base;
|
||||
@ -58,6 +58,9 @@ struct pipe_loader_sw_device {
|
||||
#define pipe_loader_sw_device(dev) ((struct pipe_loader_sw_device *)dev)
|
||||
|
||||
static const struct pipe_loader_ops pipe_loader_sw_ops;
|
||||
#ifdef HAVE_ZINK
|
||||
static const struct pipe_loader_ops pipe_loader_vk_ops;
|
||||
#endif
|
||||
|
||||
#ifdef GALLIUM_STATIC_TARGETS
|
||||
static const struct sw_driver_descriptor driver_descriptors = {
|
||||
@ -90,6 +93,37 @@ static const struct sw_driver_descriptor driver_descriptors = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(GALLIUM_STATIC_TARGETS) && defined(HAVE_ZINK)
|
||||
static const struct sw_driver_descriptor kopper_driver_descriptors = {
|
||||
.create_screen = sw_screen_create_zink,
|
||||
.winsys = {
|
||||
#ifdef HAVE_PIPE_LOADER_DRI
|
||||
{
|
||||
.name = "dri",
|
||||
.create_winsys = dri_create_sw_winsys,
|
||||
},
|
||||
#endif
|
||||
#ifdef HAVE_PIPE_LOADER_KMS
|
||||
{
|
||||
.name = "kms_dri",
|
||||
.create_winsys = kms_dri_create_winsys,
|
||||
},
|
||||
#endif
|
||||
#ifndef __ANDROID__
|
||||
{
|
||||
.name = "null",
|
||||
.create_winsys = null_sw_create,
|
||||
},
|
||||
{
|
||||
.name = "wrapped",
|
||||
.create_winsys = wrapper_sw_winsys_wrap_pipe_screen,
|
||||
},
|
||||
#endif
|
||||
{ 0 },
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
static bool
|
||||
pipe_loader_sw_probe_init_common(struct pipe_loader_sw_device *sdev)
|
||||
{
|
||||
@ -124,6 +158,42 @@ pipe_loader_sw_probe_init_common(struct pipe_loader_sw_device *sdev)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ZINK
|
||||
static bool
|
||||
pipe_loader_vk_probe_init_common(struct pipe_loader_sw_device *sdev)
|
||||
{
|
||||
sdev->base.type = PIPE_LOADER_DEVICE_PLATFORM;
|
||||
sdev->base.driver_name = "kopper";
|
||||
sdev->base.ops = &pipe_loader_vk_ops;
|
||||
sdev->fd = -1;
|
||||
|
||||
#ifdef GALLIUM_STATIC_TARGETS
|
||||
sdev->dd = &kopper_driver_descriptors;
|
||||
if (!sdev->dd)
|
||||
return false;
|
||||
#else
|
||||
const char *search_dir = getenv("GALLIUM_PIPE_SEARCH_DIR");
|
||||
if (search_dir == NULL)
|
||||
search_dir = PIPE_SEARCH_DIR;
|
||||
|
||||
sdev->lib = pipe_loader_find_module("swrast", search_dir);
|
||||
if (!sdev->lib)
|
||||
return false;
|
||||
|
||||
sdev->dd = (const struct sw_driver_descriptor *)
|
||||
util_dl_get_proc_address(sdev->lib, "swrast_driver_descriptor");
|
||||
|
||||
if (!sdev->dd){
|
||||
util_dl_close(sdev->lib);
|
||||
sdev->lib = NULL;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
pipe_loader_sw_probe_teardown_common(struct pipe_loader_sw_device *sdev)
|
||||
{
|
||||
@ -163,6 +233,37 @@ fail:
|
||||
FREE(sdev);
|
||||
return false;
|
||||
}
|
||||
#ifdef HAVE_ZINK
|
||||
bool
|
||||
pipe_loader_vk_probe_dri(struct pipe_loader_device **devs, const struct drisw_loader_funcs *drisw_lf)
|
||||
{
|
||||
struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device);
|
||||
int i;
|
||||
|
||||
if (!sdev)
|
||||
return false;
|
||||
|
||||
if (!pipe_loader_vk_probe_init_common(sdev))
|
||||
goto fail;
|
||||
|
||||
for (i = 0; sdev->dd->winsys[i].name; i++) {
|
||||
if (strcmp(sdev->dd->winsys[i].name, "dri") == 0) {
|
||||
sdev->ws = sdev->dd->winsys[i].create_winsys(drisw_lf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!sdev->ws)
|
||||
goto fail;
|
||||
|
||||
*devs = &sdev->base;
|
||||
return true;
|
||||
|
||||
fail:
|
||||
pipe_loader_sw_probe_teardown_common(sdev);
|
||||
FREE(sdev);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PIPE_LOADER_KMS
|
||||
@ -303,6 +404,19 @@ pipe_loader_sw_get_driconf(struct pipe_loader_device *dev, unsigned *count)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ZINK
|
||||
static const driOptionDescription zink_driconf[] = {
|
||||
#include "zink/driinfo_zink.h"
|
||||
};
|
||||
|
||||
static const struct driOptionDescription *
|
||||
pipe_loader_vk_get_driconf(struct pipe_loader_device *dev, unsigned *count)
|
||||
{
|
||||
*count = ARRAY_SIZE(zink_driconf);
|
||||
return zink_driconf;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct pipe_screen *
|
||||
pipe_loader_sw_create_screen(struct pipe_loader_device *dev,
|
||||
const struct pipe_screen_config *config, bool sw_vk)
|
||||
@ -310,7 +424,7 @@ pipe_loader_sw_create_screen(struct pipe_loader_device *dev,
|
||||
struct pipe_loader_sw_device *sdev = pipe_loader_sw_device(dev);
|
||||
struct pipe_screen *screen;
|
||||
|
||||
screen = sdev->dd->create_screen(sdev->ws, sw_vk);
|
||||
screen = sdev->dd->create_screen(sdev->ws, config, sw_vk);
|
||||
if (!screen)
|
||||
sdev->ws->destroy(sdev->ws);
|
||||
|
||||
@ -322,3 +436,11 @@ static const struct pipe_loader_ops pipe_loader_sw_ops = {
|
||||
.get_driconf = pipe_loader_sw_get_driconf,
|
||||
.release = pipe_loader_sw_release
|
||||
};
|
||||
|
||||
#ifdef HAVE_ZINK
|
||||
static const struct pipe_loader_ops pipe_loader_vk_ops = {
|
||||
.create_screen = pipe_loader_sw_create_screen,
|
||||
.get_driconf = pipe_loader_vk_get_driconf,
|
||||
.release = pipe_loader_sw_release
|
||||
};
|
||||
#endif
|
||||
|
@ -3,6 +3,7 @@
|
||||
#define INLINE_SW_HELPER_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_screen.h"
|
||||
#include "util/u_debug.h"
|
||||
#include "util/debug.h"
|
||||
#include "frontend/sw_winsys.h"
|
||||
@ -92,9 +93,6 @@ sw_screen_create_vk(struct sw_winsys *winsys, bool sw_vk)
|
||||
#endif
|
||||
#if defined(GALLIUM_SOFTPIPE)
|
||||
(sw_vk ? "" : "softpipe"),
|
||||
#endif
|
||||
#if defined(GALLIUM_ZINK)
|
||||
(sw_vk || only_sw) ? "" : "zink",
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -109,6 +107,16 @@ sw_screen_create_vk(struct sw_winsys *winsys, bool sw_vk)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct pipe_screen *
|
||||
sw_screen_create_zink(struct sw_winsys *winsys, const struct pipe_screen_config *config, bool whatever)
|
||||
{
|
||||
#if defined(GALLIUM_ZINK)
|
||||
return zink_create_screen(winsys, config);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline struct pipe_screen *
|
||||
sw_screen_create(struct sw_winsys *winsys)
|
||||
{
|
||||
|
@ -39,7 +39,7 @@
|
||||
#endif
|
||||
|
||||
static inline struct pipe_screen *
|
||||
sw_screen_create_named(struct sw_winsys *winsys, const char *driver)
|
||||
sw_screen_create_named(struct sw_winsys *winsys, const struct pipe_screen_config *config, const char *driver)
|
||||
{
|
||||
struct pipe_screen *screen = NULL;
|
||||
|
||||
@ -80,7 +80,7 @@ sw_screen_create_named(struct sw_winsys *winsys, const char *driver)
|
||||
}
|
||||
|
||||
struct pipe_screen *
|
||||
sw_screen_create_vk(struct sw_winsys *winsys, bool sw_vk)
|
||||
sw_screen_create_vk(struct sw_winsys *winsys, const struct pipe_screen_config *config, bool sw_vk)
|
||||
{
|
||||
UNUSED bool only_sw = env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false);
|
||||
const char *drivers[] = {
|
||||
@ -96,14 +96,11 @@ sw_screen_create_vk(struct sw_winsys *winsys, bool sw_vk)
|
||||
#endif
|
||||
#if defined(GALLIUM_SOFTPIPE)
|
||||
sw_vk ? "" : "softpipe",
|
||||
#endif
|
||||
#if defined(GALLIUM_ZINK)
|
||||
(sw_vk || only_sw) ? "" : "zink",
|
||||
#endif
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(drivers); i++) {
|
||||
struct pipe_screen *screen = sw_screen_create_named(winsys, drivers[i]);
|
||||
struct pipe_screen *screen = sw_screen_create_named(winsys, config, drivers[i]);
|
||||
if (screen)
|
||||
return screen;
|
||||
/* If the env var is set, don't keep trying things */
|
||||
@ -113,9 +110,19 @@ sw_screen_create_vk(struct sw_winsys *winsys, bool sw_vk)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct pipe_screen *
|
||||
sw_screen_create_zink(struct sw_winsys *winsys, const struct pipe_screen_config *config, bool whatever)
|
||||
{
|
||||
#if defined(GALLIUM_ZINK)
|
||||
return zink_create_screen(winsys);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct pipe_screen *
|
||||
sw_screen_create(struct sw_winsys *winsys)
|
||||
{
|
||||
return sw_screen_create_vk(winsys, false);
|
||||
return sw_screen_create_vk(winsys, NULL, false);
|
||||
}
|
||||
#endif
|
||||
|
@ -5,7 +5,9 @@ struct pipe_screen;
|
||||
struct sw_winsys;
|
||||
|
||||
struct pipe_screen *
|
||||
sw_screen_create_vk(struct sw_winsys *winsys, bool sw_vk);
|
||||
sw_screen_create_vk(struct sw_winsys *winsys, const struct pipe_screen_config *config, bool sw_vk);
|
||||
struct pipe_screen *
|
||||
sw_screen_create_zink(struct sw_winsys *winsys, const struct pipe_screen_config *config, bool whatever);
|
||||
|
||||
struct pipe_screen *
|
||||
sw_screen_create(struct sw_winsys *winsys);
|
||||
|
@ -209,7 +209,12 @@ dri2_drawable_get_buffers(struct dri_drawable *drawable,
|
||||
return buffers;
|
||||
}
|
||||
|
||||
static bool
|
||||
bool
|
||||
dri_image_drawable_get_buffers(struct dri_drawable *drawable,
|
||||
struct __DRIimageList *images,
|
||||
const enum st_attachment_type *statts,
|
||||
unsigned statts_count);
|
||||
bool
|
||||
dri_image_drawable_get_buffers(struct dri_drawable *drawable,
|
||||
struct __DRIimageList *images,
|
||||
const enum st_attachment_type *statts,
|
||||
@ -1864,6 +1869,36 @@ static const __DRIimageExtension dri2ImageExtensionTempl = {
|
||||
.createImageWithModifiers2 = NULL,
|
||||
};
|
||||
|
||||
const __DRIimageExtension driVkImageExtension = {
|
||||
.base = { __DRI_IMAGE, 20 },
|
||||
|
||||
.createImageFromName = dri2_create_image_from_name,
|
||||
.createImageFromRenderbuffer = dri2_create_image_from_renderbuffer,
|
||||
.destroyImage = dri2_destroy_image,
|
||||
.createImage = dri2_create_image,
|
||||
.queryImage = dri2_query_image,
|
||||
.dupImage = dri2_dup_image,
|
||||
.validateUsage = dri2_validate_usage,
|
||||
.createImageFromNames = dri2_from_names,
|
||||
.fromPlanar = dri2_from_planar,
|
||||
.createImageFromTexture = dri2_create_from_texture,
|
||||
.createImageFromFds = dri2_from_fds,
|
||||
.createImageFromFds2 = dri2_from_fds2,
|
||||
.createImageFromDmaBufs = dri2_from_dma_bufs,
|
||||
.blitImage = dri2_blit_image,
|
||||
.getCapabilities = dri2_get_capabilities,
|
||||
.mapImage = dri2_map_image,
|
||||
.unmapImage = dri2_unmap_image,
|
||||
.createImageWithModifiers = dri2_create_image_with_modifiers,
|
||||
.createImageFromDmaBufs2 = dri2_from_dma_bufs2,
|
||||
.createImageFromDmaBufs3 = dri2_from_dma_bufs3,
|
||||
.queryDmaBufFormats = dri2_query_dma_buf_formats,
|
||||
.queryDmaBufModifiers = dri2_query_dma_buf_modifiers,
|
||||
.queryDmaBufFormatModifierAttribs = dri2_query_dma_buf_format_modifier_attribs,
|
||||
.createImageFromRenderbuffer2 = dri2_create_image_from_renderbuffer2,
|
||||
.createImageWithModifiers2 = dri2_create_image_with_modifiers2,
|
||||
};
|
||||
|
||||
static const __DRIrobustnessExtension dri2Robustness = {
|
||||
.base = { __DRI2_ROBUSTNESS, 1 }
|
||||
};
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "frontend/opencl_interop.h"
|
||||
#include "os/os_thread.h"
|
||||
#include "postprocess/filters.h"
|
||||
#include "kopper_interface.h"
|
||||
|
||||
struct dri_context;
|
||||
struct dri_drawable;
|
||||
@ -106,6 +107,12 @@ dri_screen(__DRIscreen * sPriv)
|
||||
return (struct dri_screen *)sPriv->driverPrivate;
|
||||
}
|
||||
|
||||
static inline const __DRIkopperLoaderExtension *
|
||||
dri_screen_get_kopper(struct dri_screen *screen)
|
||||
{
|
||||
return screen->sPriv->kopper_loader;
|
||||
}
|
||||
|
||||
struct __DRIimageRec {
|
||||
struct pipe_resource *texture;
|
||||
unsigned level;
|
||||
@ -167,6 +174,8 @@ extern const struct __DriverAPIRec galliumdrm_driver_api;
|
||||
extern const __DRIextension *galliumdrm_driver_extensions[];
|
||||
extern const struct __DriverAPIRec galliumsw_driver_api;
|
||||
extern const __DRIextension *galliumsw_driver_extensions[];
|
||||
extern const struct __DriverAPIRec galliumvk_driver_api;
|
||||
extern const __DRIextension *galliumvk_driver_extensions[];
|
||||
extern const __DRIconfigOptionsExtension gallium_config_options;
|
||||
|
||||
#endif
|
||||
|
@ -88,6 +88,8 @@ setupLoaderExtensions(__DRIscreen *psp,
|
||||
psp->image.loader = (__DRIimageLoaderExtension *) extensions[i];
|
||||
if (strcmp(extensions[i]->name, __DRI_MUTABLE_RENDER_BUFFER_LOADER) == 0)
|
||||
psp->mutableRenderBuffer.loader = (__DRImutableRenderBufferLoaderExtension *) extensions[i];
|
||||
if (strcmp(extensions[i]->name, __DRI_KOPPER_LOADER) == 0)
|
||||
psp->kopper_loader = (__DRIkopperLoaderExtension *) extensions[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,7 @@
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/internal/dri_interface.h>
|
||||
#include "kopper_interface.h"
|
||||
#include "main/menums.h"
|
||||
#include "main/formats.h"
|
||||
#include "util/xmlconfig.h"
|
||||
@ -185,6 +186,7 @@ struct __DRIscreenRec {
|
||||
const __DRIextension **extensions;
|
||||
|
||||
const __DRIswrastLoaderExtension *swrast_loader;
|
||||
const __DRIkopperLoaderExtension *kopper_loader;
|
||||
|
||||
struct {
|
||||
/* Flag to indicate that this is a DRI2 screen. Many of the above
|
||||
|
@ -397,9 +397,15 @@ drisw_allocate_textures(struct dri_context *stctx,
|
||||
templ.nr_samples = 0;
|
||||
templ.nr_storage_samples = 0;
|
||||
|
||||
if (statts[i] == ST_ATTACHMENT_FRONT_LEFT &&
|
||||
screen->base.screen->resource_create_front &&
|
||||
loader->base.version >= 3) {
|
||||
if (bind & PIPE_BIND_DISPLAY_TARGET &&
|
||||
screen->base.screen->resource_create_drawable) {
|
||||
drawable->textures[statts[i]] =
|
||||
screen->base.screen->resource_create_drawable(screen->base.screen,
|
||||
&templ,
|
||||
drawable->dPriv);
|
||||
} else if (statts[i] == ST_ATTACHMENT_FRONT_LEFT &&
|
||||
screen->base.screen->resource_create_front &&
|
||||
loader->base.version >= 3) {
|
||||
drawable->textures[statts[i]] =
|
||||
screen->base.screen->resource_create_front(screen->base.screen, &templ, (const void *)drawable);
|
||||
} else
|
||||
|
591
src/gallium/frontends/dri/kopper.c
Normal file
591
src/gallium/frontends/dri/kopper.c
Normal file
@ -0,0 +1,591 @@
|
||||
/*
|
||||
* Copyright 2020 Red Hat, Inc.
|
||||
*
|
||||
* 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 without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* 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 above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* 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 NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS 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 USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "util/format/u_format.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_box.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe-loader/pipe_loader.h"
|
||||
#include "state_tracker/st_context.h"
|
||||
#include "os/os_process.h"
|
||||
#include "zink/zink_public.h"
|
||||
#include "zink/zink_instance.h"
|
||||
#include "driver_trace/tr_screen.h"
|
||||
|
||||
#include "dri_screen.h"
|
||||
#include "utils.h"
|
||||
#include "dri_context.h"
|
||||
#include "dri_drawable.h"
|
||||
#include "dri_helpers.h"
|
||||
#include "dri_query_renderer.h"
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
|
||||
struct kopper_drawable {
|
||||
struct dri_drawable base;
|
||||
struct kopper_loader_info info;
|
||||
};
|
||||
|
||||
struct kopper_screen {
|
||||
struct dri_screen base;
|
||||
struct pipe_screen *screen; //unwrapped
|
||||
};
|
||||
|
||||
extern const __DRIimageExtension driVkImageExtension;
|
||||
|
||||
static void
|
||||
kopper_flush_drawable(__DRIdrawable *dPriv)
|
||||
{
|
||||
dri_flush(dPriv->driContextPriv, dPriv, __DRI2_FLUSH_DRAWABLE, -1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
kopper_invalidate_drawable(__DRIdrawable *dPriv)
|
||||
{
|
||||
struct dri_drawable *drawable = dri_drawable(dPriv);
|
||||
|
||||
drawable->texture_stamp = dPriv->lastStamp - 1;
|
||||
|
||||
p_atomic_inc(&drawable->base.stamp);
|
||||
}
|
||||
|
||||
static const __DRI2flushExtension driVkFlushExtension = {
|
||||
.base = { __DRI2_FLUSH, 4 },
|
||||
|
||||
.flush = kopper_flush_drawable,
|
||||
.invalidate = kopper_invalidate_drawable,
|
||||
.flush_with_flags = dri_flush,
|
||||
};
|
||||
|
||||
static const __DRIrobustnessExtension dri2Robustness = {
|
||||
.base = { __DRI2_ROBUSTNESS, 1 }
|
||||
};
|
||||
|
||||
static const __DRIextension *drivk_screen_extensions[] = {
|
||||
&driTexBufferExtension.base,
|
||||
&dri2RendererQueryExtension.base,
|
||||
&dri2ConfigQueryExtension.base,
|
||||
&dri2FenceExtension.base,
|
||||
&dri2Robustness.base,
|
||||
&driVkImageExtension.base,
|
||||
&dri2FlushControlExtension.base,
|
||||
&driVkFlushExtension.base,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const __DRIconfig **
|
||||
kopper_init_screen(__DRIscreen * sPriv)
|
||||
{
|
||||
const __DRIconfig **configs;
|
||||
struct dri_screen *screen;
|
||||
struct kopper_screen *kscreen;
|
||||
struct pipe_screen *pscreen = NULL;
|
||||
|
||||
assert(sPriv->kopper_loader);
|
||||
kscreen = CALLOC_STRUCT(kopper_screen);
|
||||
if (!kscreen)
|
||||
return NULL;
|
||||
screen = &kscreen->base;
|
||||
|
||||
screen->sPriv = sPriv;
|
||||
screen->fd = sPriv->fd;
|
||||
screen->can_share_buffer = true;
|
||||
|
||||
sPriv->driverPrivate = (void *)kscreen;
|
||||
|
||||
bool success;
|
||||
if (screen->fd != -1)
|
||||
success = pipe_loader_drm_probe_fd(&screen->dev, screen->fd);
|
||||
else
|
||||
success = pipe_loader_vk_probe_dri(&screen->dev, NULL);
|
||||
if (success) {
|
||||
pscreen = pipe_loader_create_screen(screen->dev);
|
||||
dri_init_options(screen);
|
||||
}
|
||||
|
||||
if (!pscreen)
|
||||
goto fail;
|
||||
|
||||
kscreen->screen = trace_screen_unwrap(pscreen);
|
||||
|
||||
configs = dri_init_screen_helper(screen, pscreen);
|
||||
if (!configs)
|
||||
goto fail;
|
||||
|
||||
assert(pscreen->get_param(pscreen, PIPE_CAP_DEVICE_RESET_STATUS_QUERY));
|
||||
screen->has_reset_status_query = true;
|
||||
screen->lookup_egl_image = dri2_lookup_egl_image;
|
||||
sPriv->extensions = drivk_screen_extensions;
|
||||
|
||||
const __DRIimageLookupExtension *image = sPriv->dri2.image;
|
||||
if (image &&
|
||||
image->base.version >= 2 &&
|
||||
image->validateEGLImage &&
|
||||
image->lookupEGLImageValidated) {
|
||||
screen->validate_egl_image = dri2_validate_egl_image;
|
||||
screen->lookup_egl_image_validated = dri2_lookup_egl_image_validated;
|
||||
}
|
||||
|
||||
return configs;
|
||||
fail:
|
||||
dri_destroy_screen_helper(screen);
|
||||
if (screen->dev)
|
||||
pipe_loader_release(&screen->dev, 1);
|
||||
FREE(screen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// copypasta alert
|
||||
|
||||
static inline void
|
||||
drisw_present_texture(struct pipe_context *pipe, __DRIdrawable *dPriv,
|
||||
struct pipe_resource *ptex, struct pipe_box *sub_box)
|
||||
{
|
||||
struct dri_drawable *drawable = dri_drawable(dPriv);
|
||||
struct dri_screen *screen = dri_screen(drawable->sPriv);
|
||||
|
||||
screen->base.screen->flush_frontbuffer(screen->base.screen, pipe, ptex, 0, 0, drawable, sub_box);
|
||||
}
|
||||
|
||||
extern bool
|
||||
dri_image_drawable_get_buffers(struct dri_drawable *drawable,
|
||||
struct __DRIimageList *images,
|
||||
const enum st_attachment_type *statts,
|
||||
unsigned statts_count);
|
||||
|
||||
static void
|
||||
kopper_allocate_textures(struct dri_context *ctx,
|
||||
struct dri_drawable *drawable,
|
||||
const enum st_attachment_type *statts,
|
||||
unsigned statts_count)
|
||||
{
|
||||
struct dri_screen *screen = dri_screen(drawable->sPriv);
|
||||
struct pipe_resource templ;
|
||||
unsigned width, height;
|
||||
boolean resized;
|
||||
unsigned i;
|
||||
struct __DRIimageList images;
|
||||
__DRIdrawable *dri_drawable = drawable->dPriv;
|
||||
const __DRIimageLoaderExtension *image = drawable->sPriv->image.loader;
|
||||
struct kopper_drawable *cdraw = (struct kopper_drawable *)drawable;
|
||||
|
||||
width = drawable->dPriv->w;
|
||||
height = drawable->dPriv->h;
|
||||
|
||||
resized = (drawable->old_w != width ||
|
||||
drawable->old_h != height);
|
||||
|
||||
/* First get the buffers from the loader */
|
||||
if (image) {
|
||||
if (!dri_image_drawable_get_buffers(drawable, &images,
|
||||
statts, statts_count))
|
||||
return;
|
||||
}
|
||||
|
||||
if (image) {
|
||||
if (images.image_mask & __DRI_IMAGE_BUFFER_FRONT) {
|
||||
struct pipe_resource **buf =
|
||||
&drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
|
||||
struct pipe_resource *texture = images.front->texture;
|
||||
|
||||
dri_drawable->w = texture->width0;
|
||||
dri_drawable->h = texture->height0;
|
||||
|
||||
pipe_resource_reference(buf, texture);
|
||||
}
|
||||
|
||||
if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
|
||||
struct pipe_resource **buf =
|
||||
&drawable->textures[ST_ATTACHMENT_BACK_LEFT];
|
||||
struct pipe_resource *texture = images.back->texture;
|
||||
|
||||
dri_drawable->w = texture->width0;
|
||||
dri_drawable->h = texture->height0;
|
||||
|
||||
pipe_resource_reference(buf, texture);
|
||||
}
|
||||
|
||||
if (images.image_mask & __DRI_IMAGE_BUFFER_SHARED) {
|
||||
struct pipe_resource **buf =
|
||||
&drawable->textures[ST_ATTACHMENT_BACK_LEFT];
|
||||
struct pipe_resource *texture = images.back->texture;
|
||||
|
||||
dri_drawable->w = texture->width0;
|
||||
dri_drawable->h = texture->height0;
|
||||
|
||||
pipe_resource_reference(buf, texture);
|
||||
|
||||
ctx->is_shared_buffer_bound = true;
|
||||
} else {
|
||||
ctx->is_shared_buffer_bound = false;
|
||||
}
|
||||
} else {
|
||||
/* remove outdated textures */
|
||||
if (resized) {
|
||||
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
|
||||
if (drawable->textures[i] && i < ST_ATTACHMENT_DEPTH_STENCIL) {
|
||||
drawable->textures[i]->width0 = width;
|
||||
drawable->textures[i]->height0 = height;
|
||||
} else
|
||||
pipe_resource_reference(&drawable->textures[i], NULL);
|
||||
pipe_resource_reference(&drawable->msaa_textures[i], NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(&templ, 0, sizeof(templ));
|
||||
templ.target = screen->target;
|
||||
templ.width0 = width;
|
||||
templ.height0 = height;
|
||||
templ.depth0 = 1;
|
||||
templ.array_size = 1;
|
||||
templ.last_level = 0;
|
||||
bool is_window = cdraw->info.bos.sType != 0;
|
||||
|
||||
uint32_t attachments = 0;
|
||||
for (i = 0; i < statts_count; i++)
|
||||
attachments |= BITFIELD_BIT(statts[i]);
|
||||
bool front_only = attachments & ST_ATTACHMENT_FRONT_LEFT_MASK && !(attachments & ST_ATTACHMENT_BACK_LEFT_MASK);
|
||||
|
||||
for (i = 0; i < statts_count; i++) {
|
||||
enum pipe_format format;
|
||||
unsigned bind;
|
||||
|
||||
dri_drawable_get_format(drawable, statts[i], &format, &bind);
|
||||
|
||||
/* the texture already exists or not requested */
|
||||
if (!drawable->textures[statts[i]]) {
|
||||
if (statts[i] == ST_ATTACHMENT_BACK_LEFT ||
|
||||
(statts[i] == ST_ATTACHMENT_FRONT_LEFT && front_only))
|
||||
bind |= PIPE_BIND_DISPLAY_TARGET;
|
||||
|
||||
if (format == PIPE_FORMAT_NONE)
|
||||
continue;
|
||||
|
||||
templ.format = format;
|
||||
templ.bind = bind;
|
||||
templ.nr_samples = 0;
|
||||
templ.nr_storage_samples = 0;
|
||||
|
||||
if (statts[i] < ST_ATTACHMENT_DEPTH_STENCIL && is_window) {
|
||||
void *data;
|
||||
if (statts[i] == ST_ATTACHMENT_BACK_LEFT || (statts[i] == ST_ATTACHMENT_FRONT_LEFT && front_only))
|
||||
data = &cdraw->info;
|
||||
else
|
||||
data = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
|
||||
assert(data);
|
||||
drawable->textures[statts[i]] =
|
||||
screen->base.screen->resource_create_drawable(screen->base.screen, &templ, data);
|
||||
} else
|
||||
drawable->textures[statts[i]] =
|
||||
screen->base.screen->resource_create(screen->base.screen, &templ);
|
||||
}
|
||||
if (drawable->stvis.samples > 1 && !drawable->msaa_textures[statts[i]]) {
|
||||
templ.bind = templ.bind &
|
||||
~(PIPE_BIND_SCANOUT | PIPE_BIND_SHARED | PIPE_BIND_DISPLAY_TARGET);
|
||||
templ.nr_samples = drawable->stvis.samples;
|
||||
templ.nr_storage_samples = drawable->stvis.samples;
|
||||
drawable->msaa_textures[statts[i]] =
|
||||
screen->base.screen->resource_create(screen->base.screen, &templ);
|
||||
|
||||
dri_pipe_blit(ctx->st->pipe,
|
||||
drawable->msaa_textures[statts[i]],
|
||||
drawable->textures[statts[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
drawable->old_w = width;
|
||||
drawable->old_h = height;
|
||||
}
|
||||
|
||||
static inline void
|
||||
get_drawable_info(__DRIdrawable *dPriv, int *x, int *y, int *w, int *h)
|
||||
{
|
||||
__DRIscreen *sPriv = dPriv->driScreenPriv;
|
||||
const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
|
||||
|
||||
if (loader)
|
||||
loader->getDrawableInfo(dPriv,
|
||||
x, y, w, h,
|
||||
dPriv->loaderPrivate);
|
||||
}
|
||||
|
||||
static void
|
||||
kopper_update_drawable_info(struct dri_drawable *drawable)
|
||||
{
|
||||
__DRIdrawable *dPriv = drawable->dPriv;
|
||||
__DRIscreen *sPriv = dPriv->driScreenPriv;
|
||||
struct kopper_drawable *cdraw = (struct kopper_drawable *)drawable;
|
||||
bool is_window = cdraw->info.bos.sType != 0;
|
||||
int x, y;
|
||||
struct kopper_screen *kscreen = (struct kopper_screen*)sPriv->driverPrivate;
|
||||
struct pipe_screen *screen = kscreen->screen;
|
||||
struct pipe_resource *ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT] ?
|
||||
drawable->textures[ST_ATTACHMENT_BACK_LEFT] :
|
||||
drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
|
||||
|
||||
#if 0
|
||||
if (is_window && ptex && kscreen->base.fd == -1)
|
||||
zink_kopper_update(screen, ptex, &dPriv->w, &dPriv->h);
|
||||
else
|
||||
#endif
|
||||
get_drawable_info(dPriv, &x, &y, &dPriv->w, &dPriv->h);
|
||||
}
|
||||
|
||||
static inline void
|
||||
kopper_present_texture(struct pipe_context *pipe, __DRIdrawable *dPriv,
|
||||
struct pipe_resource *ptex, struct pipe_box *sub_box)
|
||||
{
|
||||
struct dri_drawable *drawable = dri_drawable(dPriv);
|
||||
struct dri_screen *screen = dri_screen(drawable->sPriv);
|
||||
|
||||
screen->base.screen->flush_frontbuffer(screen->base.screen, pipe, ptex, 0, 0, drawable, sub_box);
|
||||
}
|
||||
|
||||
static inline void
|
||||
kopper_copy_to_front(struct pipe_context *pipe,
|
||||
__DRIdrawable * dPriv,
|
||||
struct pipe_resource *ptex)
|
||||
{
|
||||
kopper_present_texture(pipe, dPriv, ptex, NULL);
|
||||
|
||||
kopper_invalidate_drawable(dPriv);
|
||||
}
|
||||
|
||||
static bool
|
||||
kopper_flush_frontbuffer(struct dri_context *ctx,
|
||||
struct dri_drawable *drawable,
|
||||
enum st_attachment_type statt)
|
||||
{
|
||||
struct pipe_resource *ptex;
|
||||
|
||||
if (!ctx || statt != ST_ATTACHMENT_FRONT_LEFT)
|
||||
return false;
|
||||
|
||||
if (drawable) {
|
||||
/* prevent recursion */
|
||||
if (drawable->flushing)
|
||||
return true;
|
||||
|
||||
drawable->flushing = true;
|
||||
}
|
||||
|
||||
if (drawable->stvis.samples > 1) {
|
||||
/* Resolve the front buffer. */
|
||||
dri_pipe_blit(ctx->st->pipe,
|
||||
drawable->textures[ST_ATTACHMENT_FRONT_LEFT],
|
||||
drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT]);
|
||||
}
|
||||
ptex = drawable->textures[statt];
|
||||
|
||||
if (ptex) {
|
||||
ctx->st->pipe->flush_resource(ctx->st->pipe, drawable->textures[ST_ATTACHMENT_FRONT_LEFT]);
|
||||
struct pipe_screen *screen = drawable->screen->base.screen;
|
||||
struct st_context_iface *st;
|
||||
struct pipe_fence_handle *new_fence = NULL;
|
||||
st = ctx->st;
|
||||
if (st->thread_finish)
|
||||
st->thread_finish(st);
|
||||
|
||||
st->flush(st, ST_FLUSH_FRONT, &new_fence, NULL, NULL);
|
||||
if (drawable) {
|
||||
drawable->flushing = false;
|
||||
}
|
||||
/* throttle on the previous fence */
|
||||
if (drawable->throttle_fence) {
|
||||
screen->fence_finish(screen, NULL, drawable->throttle_fence, PIPE_TIMEOUT_INFINITE);
|
||||
screen->fence_reference(screen, &drawable->throttle_fence, NULL);
|
||||
}
|
||||
drawable->throttle_fence = new_fence;
|
||||
kopper_copy_to_front(st->pipe, ctx->dPriv, ptex);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
kopper_update_tex_buffer(struct dri_drawable *drawable,
|
||||
struct dri_context *ctx,
|
||||
struct pipe_resource *res)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
kopper_flush_swapbuffers(struct dri_context *ctx,
|
||||
struct dri_drawable *drawable)
|
||||
{
|
||||
/* does this actually need to do anything? */
|
||||
}
|
||||
|
||||
// XXX this frees its second argument as a side effect - regardless of success
|
||||
// - since the point is to use it as the superclass initializer before we add
|
||||
// our own state. kindagross but easier than fixing the object model first.
|
||||
static struct kopper_drawable *
|
||||
kopper_create_drawable(__DRIdrawable *dPriv, struct dri_drawable *base)
|
||||
{
|
||||
struct kopper_drawable *_ret = CALLOC_STRUCT(kopper_drawable);
|
||||
|
||||
if (!_ret)
|
||||
goto out;
|
||||
struct dri_drawable *ret = &_ret->base;
|
||||
|
||||
// copy all the elements
|
||||
*ret = *base;
|
||||
|
||||
// relocate references to the old struct
|
||||
ret->base.visual = &ret->stvis;
|
||||
ret->base.st_manager_private = (void *) ret;
|
||||
dPriv->driverPrivate = ret;
|
||||
|
||||
// and fill in the vtable
|
||||
ret->allocate_textures = kopper_allocate_textures;
|
||||
ret->update_drawable_info = kopper_update_drawable_info;
|
||||
ret->flush_frontbuffer = kopper_flush_frontbuffer;
|
||||
ret->update_tex_buffer = kopper_update_tex_buffer;
|
||||
ret->flush_swapbuffers = kopper_flush_swapbuffers;
|
||||
|
||||
out:
|
||||
free(base);
|
||||
return _ret;
|
||||
}
|
||||
|
||||
static boolean
|
||||
kopper_create_buffer(__DRIscreen * sPriv,
|
||||
__DRIdrawable * dPriv,
|
||||
const struct gl_config *visual, boolean isPixmap)
|
||||
{
|
||||
struct kopper_drawable *drawable = NULL;
|
||||
|
||||
/* always pass !pixmap because it isn't "handled" or relevant */
|
||||
if (!dri_create_buffer(sPriv, dPriv, visual, false))
|
||||
return FALSE;
|
||||
|
||||
drawable = kopper_create_drawable(dPriv, dPriv->driverPrivate);
|
||||
if (!drawable)
|
||||
return FALSE;
|
||||
|
||||
drawable->info.has_alpha = visual->alphaBits > 0;
|
||||
if (sPriv->kopper_loader->SetSurfaceCreateInfo && !isPixmap)
|
||||
sPriv->kopper_loader->SetSurfaceCreateInfo(dPriv->loaderPrivate,
|
||||
&drawable->info);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
kopper_swap_buffers(__DRIdrawable *dPriv)
|
||||
{
|
||||
struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv);
|
||||
struct dri_drawable *drawable = dri_drawable(dPriv);
|
||||
struct pipe_resource *ptex;
|
||||
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
|
||||
if (!ptex)
|
||||
return;
|
||||
|
||||
drawable->texture_stamp = dPriv->lastStamp - 1;
|
||||
dri_flush(dPriv->driContextPriv, dPriv, __DRI2_FLUSH_DRAWABLE | __DRI2_FLUSH_CONTEXT, __DRI2_THROTTLE_SWAPBUFFER);
|
||||
kopper_copy_to_front(ctx->st->pipe, dPriv, ptex);
|
||||
if (!drawable->textures[ST_ATTACHMENT_FRONT_LEFT]) {
|
||||
return;
|
||||
}
|
||||
/* have to manually swap the pointers here to make frontbuffer readback work */
|
||||
drawable->textures[ST_ATTACHMENT_BACK_LEFT] = drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
|
||||
drawable->textures[ST_ATTACHMENT_FRONT_LEFT] = ptex;
|
||||
}
|
||||
|
||||
static __DRIdrawable *
|
||||
kopperCreateNewDrawable(__DRIscreen *screen,
|
||||
const __DRIconfig *config,
|
||||
void *data,
|
||||
int is_pixmap)
|
||||
{
|
||||
__DRIdrawable *pdraw;
|
||||
|
||||
assert(data != NULL);
|
||||
|
||||
pdraw = malloc(sizeof *pdraw);
|
||||
if (!pdraw)
|
||||
return NULL;
|
||||
|
||||
pdraw->loaderPrivate = data;
|
||||
|
||||
pdraw->driScreenPriv = screen;
|
||||
pdraw->driContextPriv = NULL;
|
||||
pdraw->refcount = 0;
|
||||
pdraw->lastStamp = 0;
|
||||
pdraw->w = 0;
|
||||
pdraw->h = 0;
|
||||
|
||||
//dri_get_drawable(pdraw);
|
||||
pdraw->refcount++;
|
||||
|
||||
if (!screen->driver->CreateBuffer(screen, pdraw, &config->modes,
|
||||
is_pixmap)) {
|
||||
free(pdraw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pdraw->dri2.stamp = pdraw->lastStamp + 1;
|
||||
|
||||
return pdraw;
|
||||
}
|
||||
|
||||
|
||||
const __DRIkopperExtension driKopperExtension = {
|
||||
.base = { __DRI_KOPPER, 1 },
|
||||
.createNewDrawable = kopperCreateNewDrawable,
|
||||
};
|
||||
|
||||
const struct __DriverAPIRec galliumvk_driver_api = {
|
||||
.InitScreen = kopper_init_screen,
|
||||
.DestroyScreen = dri_destroy_screen,
|
||||
.CreateBuffer = kopper_create_buffer,
|
||||
.DestroyBuffer = dri_destroy_buffer,
|
||||
.SwapBuffers = kopper_swap_buffers,
|
||||
.CopySubBuffer = NULL,
|
||||
};
|
||||
|
||||
static const struct __DRIDriverVtableExtensionRec galliumvk_vtable = {
|
||||
.base = { __DRI_DRIVER_VTABLE, 1 },
|
||||
.vtable = &galliumvk_driver_api,
|
||||
};
|
||||
|
||||
const __DRIextension *galliumvk_driver_extensions[] = {
|
||||
&driCoreExtension.base,
|
||||
&driSWRastExtension.base,
|
||||
&driDRI2Extension.base,
|
||||
&driImageDriverExtension.base,
|
||||
&driKopperExtension.base,
|
||||
&gallium_config_options.base,
|
||||
&galliumvk_vtable.base,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* vim: set sw=3 ts=8 sts=3 expandtab: */
|
@ -45,6 +45,10 @@ if with_dri2
|
||||
files_libdri += files('dri2.c')
|
||||
endif
|
||||
|
||||
if with_gallium_zink
|
||||
files_libdri += files('kopper.c')
|
||||
endif
|
||||
|
||||
libdri_c_args = []
|
||||
if with_gallium_softpipe
|
||||
libdri_c_args += '-DGALLIUM_SOFTPIPE'
|
||||
@ -55,7 +59,7 @@ libdri = static_library(
|
||||
files_libdri,
|
||||
include_directories : [
|
||||
inc_include, inc_util, inc_mesa, inc_mapi, inc_src, inc_gallium,
|
||||
inc_gallium_aux, inc_util,
|
||||
inc_gallium_aux, inc_util, inc_gallium_drivers,
|
||||
],
|
||||
c_args : [libdri_c_args],
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
|
@ -9,7 +9,7 @@ struct sw_winsys;
|
||||
|
||||
struct sw_driver_descriptor
|
||||
{
|
||||
struct pipe_screen *(*create_screen)(struct sw_winsys *ws, bool sw_vk);
|
||||
struct pipe_screen *(*create_screen)(struct sw_winsys *ws, const struct pipe_screen_config *config, bool sw_vk);
|
||||
struct {
|
||||
const char * const name;
|
||||
struct sw_winsys *(*create_winsys)();
|
||||
|
@ -227,6 +227,10 @@ struct pipe_screen {
|
||||
struct pipe_resource * (*resource_create)(struct pipe_screen *,
|
||||
const struct pipe_resource *templat);
|
||||
|
||||
struct pipe_resource * (*resource_create_drawable)(struct pipe_screen *,
|
||||
const struct pipe_resource *tmpl,
|
||||
const void *loader_private);
|
||||
|
||||
struct pipe_resource * (*resource_create_front)(struct pipe_screen *,
|
||||
const struct pipe_resource *templat,
|
||||
const void *map_front_private);
|
||||
|
@ -124,7 +124,13 @@ DEFINE_LOADER_DRM_ENTRYPOINT(lima)
|
||||
#endif
|
||||
|
||||
#if defined(GALLIUM_ZINK) && !defined(__APPLE__)
|
||||
DEFINE_LOADER_DRM_ENTRYPOINT(zink);
|
||||
const __DRIextension **__driDriverGetExtensions_zink(void);
|
||||
|
||||
PUBLIC const __DRIextension **__driDriverGetExtensions_zink(void)
|
||||
{
|
||||
return galliumvk_driver_extensions;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(GALLIUM_D3D12)
|
||||
|
@ -8,10 +8,10 @@
|
||||
#include "sw/wrapper/wrapper_sw_winsys.h"
|
||||
|
||||
PUBLIC struct pipe_screen *
|
||||
swrast_create_screen(struct sw_winsys *ws, bool sw_vk);
|
||||
swrast_create_screen(struct sw_winsys *ws, const struct pipe_screen_config *config, bool sw_vk);
|
||||
|
||||
struct pipe_screen *
|
||||
swrast_create_screen(struct sw_winsys *ws, bool sw_vk)
|
||||
swrast_create_screen(struct sw_winsys *ws, const struct pipe_screen_config *config, bool sw_vk)
|
||||
{
|
||||
struct pipe_screen *screen;
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
|
||||
#include "gbmint.h"
|
||||
#include "loader_dri_helper.h"
|
||||
#include "kopper_interface.h"
|
||||
#include "loader.h"
|
||||
#include "util/debug.h"
|
||||
#include "util/macros.h"
|
||||
@ -269,12 +270,19 @@ static const __DRIswrastLoaderExtension swrast_loader_extension = {
|
||||
.putImage2 = swrast_put_image2
|
||||
};
|
||||
|
||||
static const __DRIkopperLoaderExtension kopper_loader_extension = {
|
||||
.base = { __DRI_KOPPER_LOADER, 1 },
|
||||
|
||||
.SetSurfaceCreateInfo = NULL,
|
||||
};
|
||||
|
||||
static const __DRIextension *gbm_dri_screen_extensions[] = {
|
||||
&image_lookup_extension.base,
|
||||
&use_invalidate.base,
|
||||
&dri2_loader_extension.base,
|
||||
&image_loader_extension.base,
|
||||
&swrast_loader_extension.base,
|
||||
&kopper_loader_extension.base,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@ -509,15 +517,22 @@ dri_screen_create_sw(struct gbm_dri_device *dri)
|
||||
char *driver_name;
|
||||
int ret;
|
||||
|
||||
driver_name = strdup("kms_swrast");
|
||||
driver_name = strdup("zink");
|
||||
if (!driver_name)
|
||||
return -errno;
|
||||
|
||||
ret = dri_screen_create_dri2(dri, driver_name);
|
||||
if (ret != 0)
|
||||
ret = dri_screen_create_swrast(dri);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
if (ret != 0) {
|
||||
driver_name = strdup("kms_swrast");
|
||||
if (!driver_name)
|
||||
return -errno;
|
||||
|
||||
ret = dri_screen_create_dri2(dri, driver_name);
|
||||
if (ret != 0)
|
||||
ret = dri_screen_create_swrast(dri);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
dri->software = true;
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user