Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add set_interface for access by GDNative #46781

Merged
merged 1 commit into from
Mar 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion drivers/dummy/rasterizer_dummy.h
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,8 @@ class RasterizerStorageDummy : public RasterizerStorage {
void render_target_set_position(RID p_render_target, int p_x, int p_y) {}
void render_target_set_size(RID p_render_target, int p_width, int p_height) {}
RID render_target_get_texture(RID p_render_target) const { return RID(); }
void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {}
uint32_t render_target_get_depth_texture_id(RID p_render_target) const { return 0; }
void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id, unsigned int p_depth_id) {}
void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) {}
bool render_target_was_used(RID p_render_target) { return false; }
void render_target_clear_used(RID p_render_target) {}
Expand Down
50 changes: 47 additions & 3 deletions drivers/gles2/rasterizer_storage_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5172,7 +5172,14 @@ void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) {
texture_owner.free(rt->external.texture);
memdelete(t);

if (rt->external.depth != 0 && rt->external.depth_owned) {
glDeleteRenderbuffers(1, &rt->external.depth);
}

rt->external.fbo = 0;
rt->external.color = 0;
rt->external.depth = 0;
rt->external.depth_owned = false;
}

if (rt->depth) {
Expand Down Expand Up @@ -5297,7 +5304,19 @@ RID RasterizerStorageGLES2::render_target_get_texture(RID p_render_target) const
}
}

void RasterizerStorageGLES2::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {
uint32_t RasterizerStorageGLES2::render_target_get_depth_texture_id(RID p_render_target) const {

RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, 0);

if (rt->external.depth == 0) {
return rt->depth;
} else {
return rt->external.depth;
}
}

void RasterizerStorageGLES2::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id, unsigned int p_depth_id) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);

Expand All @@ -5307,7 +5326,7 @@ void RasterizerStorageGLES2::render_target_set_external_texture(RID p_render_tar
glDeleteFramebuffers(1, &rt->external.fbo);

// and this
if (rt->external.depth != 0) {
if (rt->external.depth != 0 && rt->external.depth_owned) {
glDeleteRenderbuffers(1, &rt->external.depth);
}

Expand Down Expand Up @@ -5387,15 +5406,31 @@ void RasterizerStorageGLES2::render_target_set_external_texture(RID p_render_tar
// On any other hardware these two modes are ignored and we do not have any MSAA,
// the normal MSAA modes need to be used to enable our two pass approach

// If we created a depth buffer before and we're now passed one, we need to clear it out
if (rt->external.depth != 0 && rt->external.depth_owned && p_depth_id != 0) {
glDeleteRenderbuffers(1, &rt->external.depth);
rt->external.depth_owned = false;
rt->external.depth = 0;
}

if (!rt->external.depth_owned) {
rt->external.depth = p_depth_id;
}

static const int msaa_value[] = { 2, 4 };
int msaa = msaa_value[rt->msaa - VS::VIEWPORT_MSAA_EXT_2X];

if (rt->external.depth == 0) {
rt->external.depth_owned = true;

// create a multisample depth buffer, we're not reusing Godots because Godot's didn't get created..
glGenRenderbuffers(1, &rt->external.depth);
glBindRenderbuffer(GL_RENDERBUFFER, rt->external.depth);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, config.depth_buffer_internalformat, rt->width, rt->height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->external.depth);
} else if (!rt->external.depth_owned) {
// we make an exception here, external plugin MUST make sure this is a proper multisample render buffer!
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->external.depth);
}

// and set our external texture as the texture...
Expand All @@ -5404,11 +5439,20 @@ void RasterizerStorageGLES2::render_target_set_external_texture(RID p_render_tar
} else
#endif
{
// if MSAA as on before, clear our render buffer
if (rt->external.depth != 0 && rt->external.depth_owned) {
glDeleteRenderbuffers(1, &rt->external.depth);
}
rt->external.depth_owned = false;
rt->external.depth = p_depth_id;

// set our texture as the destination for our framebuffer
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0);

// seeing we're rendering into this directly, better also use our depth buffer, just use our existing one :)
if (config.support_depth_texture) {
if (rt->external.depth != 0) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->external.depth, 0);
} else if (config.support_depth_texture) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
} else {
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
Expand Down
7 changes: 5 additions & 2 deletions drivers/gles2/rasterizer_storage_gles2.h
Original file line number Diff line number Diff line change
Expand Up @@ -1230,12 +1230,14 @@ class RasterizerStorageGLES2 : public RasterizerStorage {
GLuint fbo;
GLuint color;
GLuint depth;
bool depth_owned;
RID texture;

External() :
fbo(0),
color(0),
depth(0) {
depth(0),
depth_owned(false) {
}
} external;

Expand Down Expand Up @@ -1288,7 +1290,8 @@ class RasterizerStorageGLES2 : public RasterizerStorage {
virtual void render_target_set_position(RID p_render_target, int p_x, int p_y);
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height);
virtual RID render_target_get_texture(RID p_render_target) const;
virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id);
virtual uint32_t render_target_get_depth_texture_id(RID p_render_target) const;
virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id, unsigned int p_depth_id);

virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value);
virtual bool render_target_was_used(RID p_render_target);
Expand Down
60 changes: 54 additions & 6 deletions drivers/gles3/rasterizer_storage_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7196,6 +7196,8 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
memdelete(t);

rt->external.fbo = 0;
rt->external.color = 0;
rt->external.depth = 0;
}

Texture *tex = texture_owner.get(rt->texture);
Expand Down Expand Up @@ -7281,8 +7283,14 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, rt->depth, 0);
if (rt->external.depth == 0) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, rt->depth, 0);
} else {
// Use our external depth texture instead.
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, rt->external.depth, 0);
}

glGenTextures(1, &rt->color);
glBindTexture(GL_TEXTURE_2D, rt->color);
Expand Down Expand Up @@ -7664,12 +7672,31 @@ RID RasterizerStorageGLES3::render_target_get_texture(RID p_render_target) const
}
}

void RasterizerStorageGLES3::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {
uint32_t RasterizerStorageGLES3::render_target_get_depth_texture_id(RID p_render_target) const {

RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, 0);

if (rt->external.depth == 0) {
return rt->depth;
} else {
return rt->external.depth;
}
}

void RasterizerStorageGLES3::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id, unsigned int p_depth_id) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);

if (p_texture_id == 0) {
if (rt->external.fbo != 0) {
// return to our original depth buffer
if (rt->external.depth != 0 && rt->fbo != 0) {
glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
}

// free this
glDeleteFramebuffers(1, &rt->external.fbo);

Expand All @@ -7684,6 +7711,8 @@ void RasterizerStorageGLES3::render_target_set_external_texture(RID p_render_tar
memdelete(t);

rt->external.fbo = 0;
rt->external.color = 0;
rt->external.depth = 0;
}
} else {
Texture *t;
Expand Down Expand Up @@ -7728,6 +7757,7 @@ void RasterizerStorageGLES3::render_target_set_external_texture(RID p_render_tar

// set our texture
t->tex_id = p_texture_id;
rt->external.color = p_texture_id;

// size shouldn't be different
t->width = rt->width;
Expand All @@ -7740,14 +7770,32 @@ void RasterizerStorageGLES3::render_target_set_external_texture(RID p_render_tar
// set our texture as the destination for our framebuffer
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0);

// check status and unbind
// check status
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);

if (status != GL_FRAMEBUFFER_COMPLETE) {
printf("framebuffer fail, status: %x\n", status);
}

// Copy our depth texture id,
// if it's 0 then we don't use it,
// else we use it instead of our normal depth buffer
rt->external.depth = p_depth_id;

if (rt->external.depth != 0 && rt->fbo != 0) {
// Use our external depth texture instead.
glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->external.depth, 0);

// check status
GLenum status2 = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status2 != GL_FRAMEBUFFER_COMPLETE) {
printf("framebuffer fail, status: %x\n", status2);
}
}

// and unbind
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);

ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
}
}
Expand Down
10 changes: 8 additions & 2 deletions drivers/gles3/rasterizer_storage_gles3.h
Original file line number Diff line number Diff line change
Expand Up @@ -1400,10 +1400,15 @@ class RasterizerStorageGLES3 : public RasterizerStorage {
// External FBO to render our final result to (mostly used for ARVR)
struct External {
GLuint fbo;
GLuint color;
GLuint depth;
RID texture;

External() :
fbo(0) {}
fbo(0),
color(0),
depth(0) {
}
} external;

uint64_t last_exposure_tick;
Expand Down Expand Up @@ -1450,7 +1455,8 @@ class RasterizerStorageGLES3 : public RasterizerStorage {
virtual void render_target_set_position(RID p_render_target, int p_x, int p_y);
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height);
virtual RID render_target_get_texture(RID p_render_target) const;
virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id);
virtual uint32_t render_target_get_depth_texture_id(RID p_render_target) const;
virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id, unsigned int p_depth_id);

virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value);
virtual bool render_target_was_used(RID p_render_target);
Expand Down
28 changes: 28 additions & 0 deletions modules/gdnative/arvr/arvr_interface_gdnative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,17 @@ unsigned int ARVRInterfaceGDNative::get_external_texture_for_eye(ARVRInterface::
}
}

unsigned int ARVRInterfaceGDNative::get_external_depth_for_eye(ARVRInterface::Eyes p_eye) {

ERR_FAIL_COND_V(interface == NULL, 0);

if ((interface->version.major > 1) || ((interface->version.major) == 1 && (interface->version.minor >= 2))) {
return (unsigned int)interface->get_external_depth_for_eye(data, (godot_int)p_eye);
} else {
return 0;
}
}

void ARVRInterfaceGDNative::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {

ERR_FAIL_COND(interface == NULL);
Expand Down Expand Up @@ -425,4 +436,21 @@ godot_real GDAPI godot_arvr_get_controller_rumble(godot_int p_controller_id) {

return 0.0;
}

void GDAPI godot_arvr_set_interface(godot_object *p_arvr_interface, const godot_arvr_interface_gdnative *p_gdn_interface) {
// If our major version is 0 or bigger then 10, we're likely looking at our constructor pointer from an older plugin
ERR_FAIL_COND_MSG((p_gdn_interface->version.major == 0) || (p_gdn_interface->version.major > 10), "GDNative ARVR interfaces build for Godot 3.0 are not supported.");

ARVRInterfaceGDNative *interface = (ARVRInterfaceGDNative *)p_arvr_interface;
interface->set_interface((const godot_arvr_interface_gdnative *)p_gdn_interface);
}

godot_int GDAPI godot_arvr_get_depthid(godot_rid *p_render_target) {
// We also need to access our depth texture for reprojection.
RID *render_target = (RID *)p_render_target;

uint32_t texid = VSG::storage->render_target_get_depth_texture_id(*render_target);

return texid;
}
}
1 change: 1 addition & 0 deletions modules/gdnative/arvr/arvr_interface_gdnative.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class ARVRInterfaceGDNative : public ARVRInterface {
virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);

virtual unsigned int get_external_texture_for_eye(ARVRInterface::Eyes p_eye);
virtual unsigned int get_external_depth_for_eye(ARVRInterface::Eyes p_eye);
virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);

virtual void process();
Expand Down
27 changes: 26 additions & 1 deletion modules/gdnative/gdnative_api.json
Original file line number Diff line number Diff line change
Expand Up @@ -6459,7 +6459,32 @@
"major": 1,
"minor": 1
},
"next": null,
"next": {
"name": "arvr",
"type": "ARVR",
"version": {
"major": 1,
"minor": 2
},
"next": null,
"api": [
{
"name": "godot_arvr_set_interface",
"return_type": "void",
"arguments": [
["godot_object *", "p_arvr_interface"],
["const godot_arvr_interface_gdnative *", "p_gdn_interface"]
]
},
{
"name": "godot_arvr_get_depthid",
"return_type": "godot_int",
"arguments": [
["godot_rid *", "p_render_target"]
]
}
]
},
"api": [
{
"name": "godot_arvr_register_interface",
Expand Down
8 changes: 7 additions & 1 deletion modules/gdnative/include/arvr/godot_arvr.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ extern "C" {

// Use these to populate version in your plugin
#define GODOTVR_API_MAJOR 1
#define GODOTVR_API_MINOR 1
#define GODOTVR_API_MINOR 2

typedef struct {
godot_gdnative_api_version version; /* version of our API */
Expand All @@ -65,6 +65,8 @@ typedef struct {
godot_int (*get_external_texture_for_eye)(void *, godot_int);
void (*notification)(void *, godot_int);
godot_int (*get_camera_feed_id)(void *);
// only in 1.2 onwards
godot_int (*get_external_depth_for_eye)(void *, godot_int);
} godot_arvr_interface_gdnative;

void GDAPI godot_arvr_register_interface(const godot_arvr_interface_gdnative *p_interface);
Expand All @@ -85,6 +87,10 @@ void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int
void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative);
godot_real GDAPI godot_arvr_get_controller_rumble(godot_int p_controller_id);

// ARVR 1.2 functions
void GDAPI godot_arvr_set_interface(godot_object *p_arvr_interface, const godot_arvr_interface_gdnative *p_gdn_interface);
godot_int GDAPI godot_arvr_get_depthid(godot_rid *p_render_target);

#ifdef __cplusplus
}
#endif
Expand Down
5 changes: 5 additions & 0 deletions servers/arvr/arvr_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ unsigned int ARVRInterface::get_external_texture_for_eye(ARVRInterface::Eyes p_e
return 0;
};

// optional render to external depth texture which enhances performance on those platforms that require us to submit our end result into special textures.
unsigned int ARVRInterface::get_external_depth_for_eye(ARVRInterface::Eyes p_eye) {
return 0;
};

/** these will only be implemented on AR interfaces, so we want dummies for VR **/
bool ARVRInterface::get_anchor_detection_is_enabled() const {
return false;
Expand Down
Loading