WIP: Vulkan: Initial Immediate Mode Support. #106954

Closed
Jeroen Bakker wants to merge 27 commits from Jeroen-Bakker:vulkan-immediate into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
11 changed files with 91 additions and 57 deletions
Showing only changes of commit 9e83be5c40 - Show all commits

View File

@ -1234,8 +1234,13 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
tgpf->sizey = (int)tgpf->region->winy;
char err_out[256] = "unknown";
GPUOffScreen *offscreen = GPU_offscreen_create(
tgpf->sizex, tgpf->sizey, true, GPU_RGBA8, err_out);
GPUOffScreen *offscreen = GPU_offscreen_create(tgpf->sizex,
tgpf->sizey,
true,
GPU_RGBA8,
GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_HOST_READ,
err_out);
if (offscreen == NULL) {
printf("GPencil - Fill - Unable to create fill buffer\n");
return false;

View File

@ -757,7 +757,13 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
/* corrects render size with actual size, not every card supports non-power-of-two dimensions */
DRW_opengl_context_enable(); /* Off-screen creation needs to be done in DRW context. */
ofs = GPU_offscreen_create(sizex, sizey, true, GPU_RGBA16F, err_out);
ofs = GPU_offscreen_create(sizex,
sizey,
true,
GPU_RGBA16F,
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_HOST_READ,
err_out);
DRW_opengl_context_disable();
if (!ofs) {

View File

@ -425,7 +425,13 @@ static void screen_preview_draw(const bScreen *screen, int size_x, int size_y)
void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, uint *r_rect)
{
char err_out[256] = "unknown";
GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, true, GPU_RGBA8, err_out);
GPUOffScreen *offscreen = GPU_offscreen_create(
size_x,
size_y,
true,
GPU_RGBA8,
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_HOST_READ,
err_out);
GPU_offscreen_bind(offscreen, true);
GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f);

View File

@ -1886,7 +1886,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
if (own_ofs) {
/* bind */
ofs = GPU_offscreen_create(sizex, sizey, true, GPU_RGBA8, err_out);
ofs = GPU_offscreen_create(sizex,
sizey,
true,
GPU_RGBA8,
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_HOST_READ,
err_out);
if (ofs == nullptr) {
DRW_opengl_context_disable();
return nullptr;

View File

@ -589,8 +589,12 @@ typedef struct GPUOffScreen GPUOffScreen;
* If \a err_out is not `nullptr` it will be use to write any configuration error message..
* \note This function binds the framebuffer to the active context.
*/
GPUOffScreen *GPU_offscreen_create(
int width, int height, bool with_depth_buffer, eGPUTextureFormat format, char err_out[256]);
GPUOffScreen *GPU_offscreen_create(int width,
int height,
bool with_depth_buffer,
eGPUTextureFormat format,
eGPUTextureUsage usage,
char err_out[256]);
/**
* Free a #GPUOffScreen.

View File

@ -652,8 +652,12 @@ static GPUFrameBuffer *gpu_offscreen_fb_get(GPUOffScreen *ofs)
return gpu_offscreen_fb_get(ofs);
}
GPUOffScreen *GPU_offscreen_create(
int width, int height, bool depth, eGPUTextureFormat format, char err_out[256])
GPUOffScreen *GPU_offscreen_create(int width,
int height,
bool depth,
eGPUTextureFormat format,
eGPUTextureUsage usage,
char err_out[256])
{
GPUOffScreen *ofs = MEM_cnew<GPUOffScreen>(__func__);
@ -662,8 +666,6 @@ GPUOffScreen *GPU_offscreen_create(
height = max_ii(1, height);
width = max_ii(1, width);
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_HOST_READ;
ofs->color = GPU_texture_create_2d("ofs_color", width, height, 1, format, usage, nullptr);
if (depth) {

View File

@ -18,7 +18,13 @@ const size_t Size = 512;
static void test_offscreen_draw_batch_quad()
{
GPUOffScreen *offscreen = GPU_offscreen_create(Size, Size, false, GPU_RGBA16F, nullptr);
GPUOffScreen *offscreen = GPU_offscreen_create(Size,
Size,
false,
GPU_RGBA16F,
GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_HOST_READ,
nullptr);
BLI_assert(offscreen != nullptr);
GPU_offscreen_bind(offscreen, false);
/*
@ -49,7 +55,8 @@ GPU_TEST(offscreen_draw_batch_quad);
static void test_offscreen_draw_batch_sphere()
{
GPUOffScreen *offscreen = GPU_offscreen_create(Size, Size, false, GPU_RGBA16F, nullptr);
GPUOffScreen *offscreen = GPU_offscreen_create(
Size, Size, false, GPU_RGBA16F, GPU_TEXTURE_USAGE_ATTACHMENT, nullptr);
BLI_assert(offscreen != nullptr);
GPU_offscreen_bind(offscreen, false);
@ -74,40 +81,4 @@ static void test_offscreen_draw_batch_sphere()
}
GPU_TEST(offscreen_draw_batch_sphere);
template<eGPUBlend blend_type>
void offscreen_blending_test(float4 source_a, float4 source_b, float4 expected_result)
{
GPUOffScreen *offscreen = GPU_offscreen_create(1, 1, false, GPU_RGBA16F, nullptr);
BLI_assert(offscreen != nullptr);
GPU_offscreen_bind(offscreen, false);
GPUTexture *color_texture = GPU_offscreen_color_texture(offscreen);
GPU_texture_clear(color_texture, GPU_DATA_FLOAT, source_a);
GPUBatch *batch = DRW_cache_quad_get();
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
GPU_batch_uniform_4fv(batch, "color", source_b);
GPU_blend(blend_type);
GPU_batch_draw(batch);
GPU_offscreen_unbind(offscreen, false);
GPU_flush();
float4 read_back;
GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
GPU_offscreen_read_pixels(offscreen, GPU_DATA_FLOAT, &read_back);
EXPECT_EQ(read_back, expected_result);
GPU_offscreen_free(offscreen);
DRW_shape_cache_free();
}
static void test_blending_none()
{
offscreen_blending_test<GPU_BLEND_NONE>(float4(1.0f, 0.0f, 1.0f, 1.0f),
float4(0.0f, 1.0f, 0.0f, 0.5f),
float4(0.0f, 1.0f, 0.0f, 0.5f));
}
GPU_TEST(blending_none)
} // namespace blender::gpu::tests

View File

@ -18,7 +18,13 @@ namespace blender::gpu::tests {
template<eGPUBlend blend_type>
void blend_test(float4 source_a, float4 source_b, float4 expected_result)
{
GPUOffScreen *offscreen = GPU_offscreen_create(1, 1, false, GPU_RGBA16F, nullptr);
GPUOffScreen *offscreen = GPU_offscreen_create(1,
1,
false,
GPU_RGBA16F,
GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_HOST_READ,
nullptr);
BLI_assert(offscreen != nullptr);
GPU_offscreen_bind(offscreen, false);
GPUTexture *color_texture = GPU_offscreen_color_texture(offscreen);

View File

@ -232,7 +232,13 @@ static PyObject *pygpu_offscreen__tp_new(PyTypeObject *UNUSED(self),
}
if (GPU_context_active_get()) {
ofs = GPU_offscreen_create(width, height, true, pygpu_textureformat.value_found, err_out);
ofs = GPU_offscreen_create(width,
height,
true,
pygpu_textureformat.value_found,
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_HOST_READ,
err_out);
}
else {
STRNCPY(err_out, "No active GPU context found");

View File

@ -684,8 +684,13 @@ static void wm_draw_region_buffer_create(ARegion *region, bool stereo, bool use_
/* Allocate offscreen buffer if it does not exist. This one has no
* depth or multisample buffers. 3D view creates own buffers with
* the data it needs. */
GPUOffScreen *offscreen = GPU_offscreen_create(
region->winx, region->winy, false, GPU_RGBA8, NULL);
GPUOffScreen *offscreen = GPU_offscreen_create(region->winx,
region->winy,
false,
GPU_RGBA8,
GPU_TEXTURE_USAGE_SHADER_READ |
GPU_TEXTURE_USAGE_ATTACHMENT,
NULL);
if (!offscreen) {
WM_report(RPT_ERROR, "Region could not be drawn!");
return;
@ -1151,7 +1156,13 @@ static void wm_draw_window(bContext *C, wmWindow *win)
* stereo methods, but it's less efficient than drawing directly. */
const int width = WM_window_pixels_x(win);
const int height = WM_window_pixels_y(win);
GPUOffScreen *offscreen = GPU_offscreen_create(width, height, false, GPU_RGBA8, NULL);
GPUOffScreen *offscreen = GPU_offscreen_create(width,
height,
false,
GPU_RGBA8,
GPU_TEXTURE_USAGE_SHADER_READ |
GPU_TEXTURE_USAGE_ATTACHMENT,
NULL);
if (offscreen) {
GPUTexture *texture = GPU_offscreen_color_texture(offscreen);
@ -1226,7 +1237,13 @@ uint *WM_window_pixels_read_offscreen(bContext *C, wmWindow *win, int r_size[2])
r_size[0] = WM_window_pixels_x(win);
r_size[1] = WM_window_pixels_y(win);
GPUOffScreen *offscreen = GPU_offscreen_create(r_size[0], r_size[1], false, GPU_RGBA8, NULL);
GPUOffScreen *offscreen = GPU_offscreen_create(r_size[0],
r_size[1],
false,
GPU_RGBA8,
GPU_TEXTURE_USAGE_SHADER_READ |
GPU_TEXTURE_USAGE_ATTACHMENT,
NULL);
if (UNLIKELY(!offscreen)) {
return NULL;
}

View File

@ -1387,8 +1387,13 @@ bool wm_xr_session_surface_offscreen_ensure(wmXrSurfaceData *surface_data,
}
BLI_assert(format != GPU_R8);
offscreen = vp->offscreen = GPU_offscreen_create(
draw_view->width, draw_view->height, true, format, err_out);
offscreen = vp->offscreen = GPU_offscreen_create(draw_view->width,
draw_view->height,
true,
format,
GPU_TEXTURE_USAGE_SHADER_READ |
GPU_TEXTURE_USAGE_ATTACHMENT,
err_out);
if (offscreen) {
viewport = vp->viewport = GPU_viewport_create();
if (!viewport) {