summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp5
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp52
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h11
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp24
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h23
-rw-r--r--drivers/gles3/shader_gles3.cpp6
-rw-r--r--drivers/gles3/shaders/scene.glsl6
-rw-r--r--drivers/unix/rw_lock_posix.cpp2
-rw-r--r--drivers/unix/stream_peer_tcp_posix.cpp4
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp84
-rw-r--r--drivers/wasapi/audio_driver_wasapi.h2
11 files changed, 151 insertions, 68 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 5b3e43fc43..0839f930c9 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -208,6 +208,8 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con
} else {
+ texture = texture->get_ptr();
+
if (texture->render_target)
texture->render_target->used_in_frame = true;
@@ -243,6 +245,7 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con
} else {
+ normal_map = normal_map->get_ptr();
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
state.current_normal = p_normal_map;
@@ -1115,6 +1118,8 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
continue;
}
+ t = t->get_ptr();
+
if (storage->config.srgb_decode_supported && t->using_srgb) {
//no srgb in 2D
glTexParameteri(t->target, _TEXTURE_SRGB_DECODE_EXT, _SKIP_DECODE_EXT);
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 02df170da1..3031b70f70 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1235,6 +1235,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m
} else {
+ t = t->get_ptr(); //resolve for proxies
#ifdef TOOLS_ENABLED
if (t->detect_3d) {
t->detect_3d(t->detect_3d_ud);
@@ -2164,7 +2165,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
state.scene_shader.set_conditional(SceneShaderGLES3::USE_OPAQUE_PREPASS, false);
}
-void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_pass) {
+void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_pass, bool p_shadow_pass) {
RasterizerStorageGLES3::Material *m = NULL;
RID m_src = p_instance->material_override.is_valid() ? p_instance->material_override : (p_material >= 0 ? p_instance->materials[p_material] : p_geometry->material);
@@ -2196,17 +2197,17 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
ERR_FAIL_COND(!m);
- _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_depth_pass);
+ _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_depth_pass, p_shadow_pass);
while (m->next_pass.is_valid()) {
m = storage->material_owner.getornull(m->next_pass);
if (!m || !m->shader || !m->shader->valid)
break;
- _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_depth_pass);
+ _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_depth_pass, p_shadow_pass);
}
}
-void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass) {
+void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass, bool p_shadow_pass) {
bool has_base_alpha = (p_material->shader->spatial.uses_alpha && !p_material->shader->spatial.uses_alpha_scissor) || p_material->shader->spatial.uses_screen_texture;
bool has_blend_alpha = p_material->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX;
@@ -2238,11 +2239,11 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
if (!p_material->shader->spatial.uses_alpha_scissor && !p_material->shader->spatial.writes_modelview_or_projection && !p_material->shader->spatial.uses_vertex && !p_material->shader->spatial.uses_discard && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
//shader does not use discard and does not write a vertex position, use generic material
if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) {
- p_material = storage->material_owner.getptr(default_material_twosided);
+ p_material = storage->material_owner.getptr(!p_shadow_pass && p_material->shader->spatial.uses_world_coordinates ? default_worldcoord_material_twosided : default_material_twosided);
no_cull = true;
mirror = false;
} else {
- p_material = storage->material_owner.getptr(default_material);
+ p_material = storage->material_owner.getptr(!p_shadow_pass && p_material->shader->spatial.uses_world_coordinates ? default_worldcoord_material : default_material);
}
}
@@ -2280,13 +2281,15 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
}
e->sort_key |= uint64_t(e->material->index) << RenderList::SORT_KEY_MATERIAL_INDEX_SHIFT;
- e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT;
if (e->instance->gi_probe_instances.size()) {
e->sort_key |= SORT_KEY_GI_PROBES_FLAG;
}
e->sort_key |= uint64_t(p_material->render_priority + 128) << RenderList::SORT_KEY_PRIORITY_SHIFT;
+ } else {
+ e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT;
+ e->sort_key |= uint64_t(e->material->index) << RenderList::SORT_KEY_MATERIAL_INDEX_SHIFT;
}
/*
@@ -3060,7 +3063,7 @@ void RasterizerSceneGLES3::_copy_texture_to_front_buffer(GLuint p_texture) {
storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, false);
}
-void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass) {
+void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass) {
current_geometry_index = 0;
current_material_index = 0;
@@ -3085,7 +3088,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
int mat_idx = inst->materials[i].is_valid() ? i : -1;
RasterizerStorageGLES3::Surface *s = mesh->surfaces[i];
- _add_geometry(s, inst, NULL, mat_idx, p_depth_pass);
+ _add_geometry(s, inst, NULL, mat_idx, p_depth_pass, p_shadow_pass);
}
//mesh->last_pass=frame;
@@ -3108,7 +3111,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
for (int i = 0; i < ssize; i++) {
RasterizerStorageGLES3::Surface *s = mesh->surfaces[i];
- _add_geometry(s, inst, multi_mesh, -1, p_depth_pass);
+ _add_geometry(s, inst, multi_mesh, -1, p_depth_pass, p_shadow_pass);
}
} break;
@@ -3117,7 +3120,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getptr(inst->base);
ERR_CONTINUE(!immediate);
- _add_geometry(immediate, inst, NULL, -1, p_depth_pass);
+ _add_geometry(immediate, inst, NULL, -1, p_depth_pass, p_shadow_pass);
} break;
case VS::INSTANCE_PARTICLES: {
@@ -3139,7 +3142,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
for (int j = 0; j < ssize; j++) {
RasterizerStorageGLES3::Surface *s = mesh->surfaces[j];
- _add_geometry(s, inst, particles, -1, p_depth_pass);
+ _add_geometry(s, inst, particles, -1, p_depth_pass, p_shadow_pass);
}
}
@@ -4055,8 +4058,8 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
render_list.clear();
- _fill_render_list(p_cull_result, p_cull_count, true);
- render_list.sort_by_depth(false);
+ _fill_render_list(p_cull_result, p_cull_count, true, false);
+ render_list.sort_by_key(false);
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_DEPTH, true);
_render_list(render_list.elements, render_list.element_count, p_cam_transform, p_cam_projection, 0, false, false, true, false, false);
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_DEPTH, false);
@@ -4086,11 +4089,10 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
_setup_lights(p_light_cull_result, p_light_cull_count, p_cam_transform.affine_inverse(), p_cam_projection, p_shadow_atlas);
_setup_reflections(p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_cam_transform.affine_inverse(), p_cam_projection, p_reflection_atlas, env);
- render_list.clear();
-
bool use_mrt = false;
- _fill_render_list(p_cull_result, p_cull_count, false);
+ render_list.clear();
+ _fill_render_list(p_cull_result, p_cull_count, false, false);
//
glEnable(GL_BLEND);
@@ -4593,10 +4595,8 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_
}
}
- //todo hacer que se redibuje cuando corresponde
-
render_list.clear();
- _fill_render_list(p_cull_result, p_cull_count, true);
+ _fill_render_list(p_cull_result, p_cull_count, true, true);
render_list.sort_by_depth(false); //shadow is front to back for performance
@@ -4760,6 +4760,18 @@ void RasterizerSceneGLES3::initialize() {
default_material_twosided = storage->material_create();
storage->shader_set_code(default_shader_twosided, "shader_type spatial; render_mode cull_disabled;\n");
storage->material_set_shader(default_material_twosided, default_shader_twosided);
+
+ //default for shaders using world coordinates (typical for triplanar)
+
+ default_worldcoord_shader = storage->shader_create();
+ storage->shader_set_code(default_worldcoord_shader, "shader_type spatial; render_mode world_vertex_coords;\n");
+ default_worldcoord_material = storage->material_create();
+ storage->material_set_shader(default_worldcoord_material, default_worldcoord_shader);
+
+ default_worldcoord_shader_twosided = storage->shader_create();
+ default_worldcoord_material_twosided = storage->material_create();
+ storage->shader_set_code(default_worldcoord_shader_twosided, "shader_type spatial; render_mode cull_disabled,world_vertex_coords;\n");
+ storage->material_set_shader(default_worldcoord_material_twosided, default_worldcoord_shader_twosided);
}
{
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 69b43c7813..99c8044e2f 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -78,6 +78,11 @@ public:
RID default_shader;
RID default_shader_twosided;
+ RID default_worldcoord_material;
+ RID default_worldcoord_material_twosided;
+ RID default_worldcoord_shader;
+ RID default_worldcoord_shader_twosided;
+
RID default_overdraw_material;
RID default_overdraw_shader;
@@ -812,9 +817,9 @@ public:
void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const CameraMatrix &p_projection, GLuint p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows);
- _FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_pass);
+ _FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_pass,bool p_shadow_pass);
- _FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass);
+ _FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass, bool p_shadow_pass);
void _draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy);
@@ -827,7 +832,7 @@ public:
void _copy_to_front_buffer(Environment *env);
void _copy_texture_to_front_buffer(GLuint p_texture); //used for debug
- void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass);
+ void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass);
void _blur_effect_buffer();
void _render_mrts(Environment *env, const CameraMatrix &p_cam_projection);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index fc9150ecdc..cba9f08537 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1232,6 +1232,25 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_
return texture_owner.make_rid(ctex);
}
+void RasterizerStorageGLES3::texture_set_proxy(RID p_texture, RID p_proxy) {
+
+ Texture *texture = texture_owner.get(p_texture);
+ ERR_FAIL_COND(!texture);
+
+ if (texture->proxy) {
+ texture->proxy->proxy_owners.erase(texture);
+ texture->proxy = NULL;
+ }
+
+ if (p_proxy.is_valid()) {
+ Texture *proxy = texture_owner.get(p_proxy);
+ ERR_FAIL_COND(!proxy);
+ ERR_FAIL_COND(proxy == texture);
+ proxy->proxy_owners.insert(texture);
+ texture->proxy = proxy;
+ }
+}
+
RID RasterizerStorageGLES3::sky_create() {
Sky *sky = memnew(Sky);
@@ -1601,6 +1620,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->spatial.uses_screen_texture = false;
p_shader->spatial.uses_vertex = false;
p_shader->spatial.writes_modelview_or_projection = false;
+ p_shader->spatial.uses_world_coordinates = false;
shaders.actions_scene.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_ADD);
shaders.actions_scene.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MIX);
@@ -1621,9 +1641,10 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
shaders.actions_scene.render_mode_flags["vertex_lighting"] = &p_shader->spatial.uses_vertex_lighting;
+ shaders.actions_scene.render_mode_flags["world_vertex_coords"] = &p_shader->spatial.uses_world_coordinates;
+
shaders.actions_scene.usage_flag_pointers["ALPHA"] = &p_shader->spatial.uses_alpha;
shaders.actions_scene.usage_flag_pointers["ALPHA_SCISSOR"] = &p_shader->spatial.uses_alpha_scissor;
- shaders.actions_scene.usage_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex;
shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"] = &p_shader->spatial.uses_sss;
shaders.actions_scene.usage_flag_pointers["DISCARD"] = &p_shader->spatial.uses_discard;
@@ -1632,6 +1653,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
+ shaders.actions_scene.write_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex;
actions = &shaders.actions_scene;
actions->uniforms = &p_shader->uniforms;
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 0ec110ab87..d5efd5307c 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -242,6 +242,9 @@ public:
struct Texture : public RID_Data {
+ Texture *proxy;
+ Set<Texture *> proxy_owners;
+
String path;
uint32_t flags;
int width, height;
@@ -301,6 +304,15 @@ public:
detect_srgb_ud = NULL;
detect_normal = NULL;
detect_normal_ud = NULL;
+ proxy = NULL;
+ }
+
+ _ALWAYS_INLINE_ Texture *get_ptr() {
+ if (proxy) {
+ return proxy; //->get_ptr(); only one level of indirection, else not inlining possible.
+ } else {
+ return this;
+ }
}
~Texture() {
@@ -309,6 +321,14 @@ public:
glDeleteTextures(1, &tex_id);
}
+
+ for (Set<Texture *>::Element *E = proxy_owners.front(); E; E = E->next()) {
+ E->get()->proxy = NULL;
+ }
+
+ if (proxy) {
+ proxy->proxy_owners.erase(this);
+ }
}
};
@@ -343,6 +363,8 @@ public:
virtual void texture_set_detect_srgb_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata);
virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata);
+ virtual void texture_set_proxy(RID p_texture, RID p_proxy);
+
/* SKY API */
struct Sky : public RID_Data {
@@ -453,6 +475,7 @@ public:
bool uses_time;
bool writes_modelview_or_projection;
bool uses_vertex_lighting;
+ bool uses_world_coordinates;
} spatial;
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index d4ef256a33..9e234f5005 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -343,7 +343,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
glDeleteProgram(v.id);
v.id = 0;
- ERR_PRINT("NO LOG, WTF");
+ ERR_PRINT("Vertex shader compilation failed with empty log");
} else {
if (iloglen == 0) {
@@ -451,7 +451,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
glDeleteShader(v.vert_id);
glDeleteProgram(v.id);
v.id = 0;
- ERR_PRINT("NO LOG, WTF");
+ ERR_PRINT("Fragment shader compilation failed with empty log");
} else {
if (iloglen == 0) {
@@ -624,7 +624,7 @@ void ShaderGLES3::setup(const char **p_conditional_defines, int p_conditional_co
feedbacks = p_feedback;
feedback_count = p_feedback_count;
- //split vertex and shader code (thank you, retarded shader compiler programmers from you know what company).
+ //split vertex and shader code (thank you, shader compiler programmers from you know what company).
{
String globals_tag = "\nVERTEX_SHADER_GLOBALS";
String material_tag = "\nMATERIAL_UNIFORMS";
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index b2b10fdb11..676541649c 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -263,6 +263,10 @@ uniform highp sampler2D skeleton_texture; //texunit:-1
out highp vec4 position_interp;
+// FIXME: This triggers a Mesa bug that breaks rendering, so disabled for now.
+// See GH-13450 and https://bugs.freedesktop.org/show_bug.cgi?id=100316
+//invariant gl_Position;
+
void main() {
highp vec4 vertex = vertex_attrib; // vec4(vertex_attrib.xyz * data_attrib.x,1.0);
@@ -1026,7 +1030,7 @@ LIGHT_SHADER_CODE
#if defined(LIGHT_USE_RIM)
- float rim_light = pow(1.0-cNdotV, (1.0-roughness)*16.0);
+ float rim_light = pow(max(0.0,1.0-cNdotV), max(0.0,(1.0-roughness)*16.0));
diffuse_light += rim_light * rim * mix(vec3(1.0),diffuse_color,rim_tint) * light_color;
#endif
}
diff --git a/drivers/unix/rw_lock_posix.cpp b/drivers/unix/rw_lock_posix.cpp
index ab2d6495bd..00125809c0 100644
--- a/drivers/unix/rw_lock_posix.cpp
+++ b/drivers/unix/rw_lock_posix.cpp
@@ -39,7 +39,7 @@ void RWLockPosix::read_lock() {
int err = pthread_rwlock_rdlock(&rwlock);
if (err != 0) {
- perror("wtf: ");
+ perror("Acquiring lock failed");
}
ERR_FAIL_COND(err != 0);
}
diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp
index 3bc2397e6f..e88a7d7de1 100644
--- a/drivers/unix/stream_peer_tcp_posix.cpp
+++ b/drivers/unix/stream_peer_tcp_posix.cpp
@@ -213,7 +213,7 @@ Error StreamPeerTCPPosix::write(const uint8_t *p_data, int p_bytes, int &r_sent,
if (errno != EAGAIN) {
- perror("shit?");
+ perror("Nothing sent");
disconnect_from_host();
ERR_PRINT("Server disconnected!\n");
return FAILED;
@@ -270,7 +270,7 @@ Error StreamPeerTCPPosix::read(uint8_t *p_buffer, int p_bytes, int &r_received,
if (errno != EAGAIN) {
- perror("shit?");
+ perror("Nothing read");
disconnect_from_host();
ERR_PRINT("Server disconnected!\n");
return FAILED;
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index 2c87fb58db..10b6a61b2d 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -74,21 +74,22 @@ Error AudioDriverWASAPI::init_device(bool reinit) {
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
// Since we're using WASAPI Shared Mode we can't control any of these, we just tag along
- channels = pwfex->nChannels;
+ wasapi_channels = pwfex->nChannels;
mix_rate = pwfex->nSamplesPerSec;
format_tag = pwfex->wFormatTag;
bits_per_sample = pwfex->wBitsPerSample;
- switch (channels) {
+ switch (wasapi_channels) {
case 2: // Stereo
case 4: // Surround 3.1
case 6: // Surround 5.1
case 8: // Surround 7.1
+ channels = wasapi_channels;
break;
default:
- ERR_PRINTS("WASAPI: Unsupported number of channels: " + itos(channels));
- ERR_FAIL_V(ERR_CANT_OPEN);
+ WARN_PRINTS("WASAPI: Unsupported number of channels: " + itos(wasapi_channels));
+ channels = 2;
break;
}
@@ -206,6 +207,35 @@ AudioDriver::SpeakerMode AudioDriverWASAPI::get_speaker_mode() const {
return get_speaker_mode_by_total_channels(channels);
}
+void AudioDriverWASAPI::write_sample(AudioDriverWASAPI *ad, BYTE *buffer, int i, int32_t sample) {
+ if (ad->format_tag == WAVE_FORMAT_PCM) {
+ switch (ad->bits_per_sample) {
+ case 8:
+ ((int8_t *)buffer)[i] = sample >> 24;
+ break;
+
+ case 16:
+ ((int16_t *)buffer)[i] = sample >> 16;
+ break;
+
+ case 24:
+ ((int8_t *)buffer)[i * 3 + 2] = sample >> 24;
+ ((int8_t *)buffer)[i * 3 + 1] = sample >> 16;
+ ((int8_t *)buffer)[i * 3 + 0] = sample >> 8;
+ break;
+
+ case 32:
+ ((int32_t *)buffer)[i] = sample;
+ break;
+ }
+ } else if (ad->format_tag == WAVE_FORMAT_IEEE_FLOAT) {
+ ((float *)buffer)[i] = (sample >> 16) / 32768.f;
+ } else {
+ ERR_PRINT("WASAPI: Unknown format tag");
+ ad->exit_thread = true;
+ }
+}
+
void AudioDriverWASAPI::thread_func(void *p_udata) {
AudioDriverWASAPI *ad = (AudioDriverWASAPI *)p_udata;
@@ -240,42 +270,21 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
if (hr == S_OK) {
// We're using WASAPI Shared Mode so we must convert the buffer
- if (ad->format_tag == WAVE_FORMAT_PCM) {
- switch (ad->bits_per_sample) {
- case 8:
- for (unsigned int i = 0; i < write_frames * ad->channels; i++) {
- ((int8_t *)buffer)[i] = ad->samples_in[buffer_idx++] >> 24;
- }
- break;
-
- case 16:
- for (unsigned int i = 0; i < write_frames * ad->channels; i++) {
- ((int16_t *)buffer)[i] = ad->samples_in[buffer_idx++] >> 16;
- }
- break;
-
- case 24:
- for (unsigned int i = 0; i < write_frames * ad->channels; i++) {
- int32_t sample = ad->samples_in[buffer_idx++];
- ((int8_t *)buffer)[i * 3 + 2] = sample >> 24;
- ((int8_t *)buffer)[i * 3 + 1] = sample >> 16;
- ((int8_t *)buffer)[i * 3 + 0] = sample >> 8;
- }
- break;
-
- case 32:
- for (unsigned int i = 0; i < write_frames * ad->channels; i++) {
- ((int32_t *)buffer)[i] = ad->samples_in[buffer_idx++];
- }
- break;
- }
- } else if (ad->format_tag == WAVE_FORMAT_IEEE_FLOAT) {
+ if (ad->channels == ad->wasapi_channels) {
for (unsigned int i = 0; i < write_frames * ad->channels; i++) {
- ((float *)buffer)[i] = (ad->samples_in[buffer_idx++] >> 16) / 32768.f;
+ ad->write_sample(ad, buffer, i, ad->samples_in[buffer_idx++]);
}
} else {
- ERR_PRINT("WASAPI: Unknown format tag");
- ad->exit_thread = true;
+ for (unsigned int i = 0; i < write_frames; i++) {
+ for (unsigned int j = 0; j < MIN(ad->channels, ad->wasapi_channels); j++) {
+ ad->write_sample(ad, buffer, i * ad->wasapi_channels + j, ad->samples_in[buffer_idx++]);
+ }
+ if (ad->wasapi_channels > ad->channels) {
+ for (unsigned int j = ad->channels; j < ad->wasapi_channels; j++) {
+ ad->write_sample(ad, buffer, i * ad->wasapi_channels + j, 0);
+ }
+ }
+ }
}
hr = ad->render_client->ReleaseBuffer(write_frames, 0);
@@ -380,6 +389,7 @@ AudioDriverWASAPI::AudioDriverWASAPI() {
buffer_size = 0;
channels = 0;
+ wasapi_channels = 0;
mix_rate = 0;
buffer_frames = 0;
diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h
index 87a2db724c..5921645f6e 100644
--- a/drivers/wasapi/audio_driver_wasapi.h
+++ b/drivers/wasapi/audio_driver_wasapi.h
@@ -55,6 +55,7 @@ class AudioDriverWASAPI : public AudioDriver {
unsigned int buffer_size;
unsigned int channels;
+ unsigned int wasapi_channels;
int mix_rate;
int buffer_frames;
@@ -62,6 +63,7 @@ class AudioDriverWASAPI : public AudioDriver {
mutable bool exit_thread;
bool active;
+ _FORCE_INLINE_ void write_sample(AudioDriverWASAPI *ad, BYTE *buffer, int i, int32_t sample);
static void thread_func(void *p_udata);
Error init_device(bool reinit = false);