├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md └── workflows │ └── artifacts.yml ├── LICENSE ├── README.md ├── RELEASE ├── build-win32.txt ├── build-win64.txt ├── dxvk.conf ├── include ├── openvr │ ├── LICENSE │ └── openvr.hpp ├── spirv │ ├── GLSL.std.450.h │ ├── GLSL.std.450.hpp │ └── spirv.hpp └── vulkan │ ├── vk_platform.h │ ├── vulkan.h │ ├── vulkan_core.h │ └── vulkan_win32.h ├── lib ├── d3dcompiler_43.lib ├── libd3dcompiler_43.def └── vulkan-1.lib ├── lib32 ├── d3dcompiler_43.lib ├── libd3dcompiler_43.def └── vulkan-1.lib ├── meson.build ├── meson_options.txt ├── package-release.sh ├── setup_dxvk.sh ├── src ├── d3d10 │ ├── d3d10.def │ ├── d3d10_1.def │ ├── d3d10_blend.cpp │ ├── d3d10_blend.h │ ├── d3d10_buffer.cpp │ ├── d3d10_buffer.h │ ├── d3d10_core.cpp │ ├── d3d10_depth_stencil.cpp │ ├── d3d10_depth_stencil.h │ ├── d3d10_device.cpp │ ├── d3d10_device.h │ ├── d3d10_include.h │ ├── d3d10_input_layout.cpp │ ├── d3d10_input_layout.h │ ├── d3d10_interfaces.h │ ├── d3d10_main.cpp │ ├── d3d10_multithread.cpp │ ├── d3d10_multithread.h │ ├── d3d10_query.cpp │ ├── d3d10_query.h │ ├── d3d10_rasterizer.cpp │ ├── d3d10_rasterizer.h │ ├── d3d10_reflection.cpp │ ├── d3d10_reflection.h │ ├── d3d10_sampler.cpp │ ├── d3d10_sampler.h │ ├── d3d10_shader.h │ ├── d3d10_state_block.cpp │ ├── d3d10_state_block.h │ ├── d3d10_texture.cpp │ ├── d3d10_texture.h │ ├── d3d10_util.cpp │ ├── d3d10_util.h │ ├── d3d10_view_dsv.cpp │ ├── d3d10_view_dsv.h │ ├── d3d10_view_rtv.cpp │ ├── d3d10_view_rtv.h │ ├── d3d10_view_srv.cpp │ ├── d3d10_view_srv.h │ ├── d3d10core.def │ ├── meson.build │ ├── version10.rc │ ├── version10_1.rc │ └── version10_core.rc ├── d3d11 │ ├── d3d11.def │ ├── d3d11_annotation.cpp │ ├── d3d11_annotation.h │ ├── d3d11_blend.cpp │ ├── d3d11_blend.h │ ├── d3d11_buffer.cpp │ ├── d3d11_buffer.h │ ├── d3d11_class_linkage.cpp │ ├── d3d11_class_linkage.h │ ├── d3d11_cmd.h │ ├── d3d11_cmdlist.cpp │ ├── d3d11_cmdlist.h │ ├── d3d11_context.cpp │ ├── d3d11_context.h │ ├── d3d11_context_def.cpp │ ├── d3d11_context_def.h │ ├── d3d11_context_ext.cpp │ ├── d3d11_context_ext.h │ ├── d3d11_context_imm.cpp │ ├── d3d11_context_imm.h │ ├── d3d11_context_state.h │ ├── d3d11_cuda.cpp │ ├── d3d11_cuda.h │ ├── d3d11_depth_stencil.cpp │ ├── d3d11_depth_stencil.h │ ├── d3d11_device.cpp │ ├── d3d11_device.h │ ├── d3d11_device_child.h │ ├── d3d11_enums.cpp │ ├── d3d11_enums.h │ ├── d3d11_gdi.cpp │ ├── d3d11_gdi.h │ ├── d3d11_include.h │ ├── d3d11_initializer.cpp │ ├── d3d11_initializer.h │ ├── d3d11_input_layout.cpp │ ├── d3d11_input_layout.h │ ├── d3d11_interfaces.h │ ├── d3d11_interop.cpp │ ├── d3d11_interop.h │ ├── d3d11_main.cpp │ ├── d3d11_options.cpp │ ├── d3d11_options.h │ ├── d3d11_query.cpp │ ├── d3d11_query.h │ ├── d3d11_rasterizer.cpp │ ├── d3d11_rasterizer.h │ ├── d3d11_resource.cpp │ ├── d3d11_resource.h │ ├── d3d11_sampler.cpp │ ├── d3d11_sampler.h │ ├── d3d11_shader.cpp │ ├── d3d11_shader.h │ ├── d3d11_state.cpp │ ├── d3d11_state.h │ ├── d3d11_state_object.cpp │ ├── d3d11_state_object.h │ ├── d3d11_swapchain.cpp │ ├── d3d11_swapchain.h │ ├── d3d11_texture.cpp │ ├── d3d11_texture.h │ ├── d3d11_util.cpp │ ├── d3d11_util.h │ ├── d3d11_video.cpp │ ├── d3d11_video.h │ ├── d3d11_view.h │ ├── d3d11_view_dsv.cpp │ ├── d3d11_view_dsv.h │ ├── d3d11_view_rtv.cpp │ ├── d3d11_view_rtv.h │ ├── d3d11_view_srv.cpp │ ├── d3d11_view_srv.h │ ├── d3d11_view_uav.cpp │ ├── d3d11_view_uav.h │ ├── meson.build │ ├── shaders │ │ ├── d3d11_video_blit_frag.frag │ │ └── d3d11_video_blit_vert.vert │ └── version.rc ├── d3d9 │ ├── d3d9.def │ ├── d3d9_adapter.cpp │ ├── d3d9_adapter.h │ ├── d3d9_buffer.cpp │ ├── d3d9_buffer.h │ ├── d3d9_caps.h │ ├── d3d9_common_buffer.cpp │ ├── d3d9_common_buffer.h │ ├── d3d9_common_texture.cpp │ ├── d3d9_common_texture.h │ ├── d3d9_constant_layout.h │ ├── d3d9_constant_set.h │ ├── d3d9_cursor.cpp │ ├── d3d9_cursor.h │ ├── d3d9_device.cpp │ ├── d3d9_device.h │ ├── d3d9_device_child.h │ ├── d3d9_fixed_function.cpp │ ├── d3d9_fixed_function.h │ ├── d3d9_format.cpp │ ├── d3d9_format.h │ ├── d3d9_format_helpers.cpp │ ├── d3d9_format_helpers.h │ ├── d3d9_hud.cpp │ ├── d3d9_hud.h │ ├── d3d9_include.h │ ├── d3d9_initializer.cpp │ ├── d3d9_initializer.h │ ├── d3d9_interface.cpp │ ├── d3d9_interface.h │ ├── d3d9_main.cpp │ ├── d3d9_monitor.cpp │ ├── d3d9_monitor.h │ ├── d3d9_multithread.cpp │ ├── d3d9_multithread.h │ ├── d3d9_names.cpp │ ├── d3d9_names.h │ ├── d3d9_options.cpp │ ├── d3d9_options.h │ ├── d3d9_query.cpp │ ├── d3d9_query.h │ ├── d3d9_resource.h │ ├── d3d9_sampler.cpp │ ├── d3d9_sampler.h │ ├── d3d9_shader.cpp │ ├── d3d9_shader.h │ ├── d3d9_shader_permutations.h │ ├── d3d9_shader_validator.h │ ├── d3d9_spec_constants.h │ ├── d3d9_state.cpp │ ├── d3d9_state.h │ ├── d3d9_stateblock.cpp │ ├── d3d9_stateblock.h │ ├── d3d9_subresource.h │ ├── d3d9_surface.cpp │ ├── d3d9_surface.h │ ├── d3d9_swapchain.cpp │ ├── d3d9_swapchain.h │ ├── d3d9_swvp_emu.cpp │ ├── d3d9_swvp_emu.h │ ├── d3d9_texture.cpp │ ├── d3d9_texture.h │ ├── d3d9_util.cpp │ ├── d3d9_util.h │ ├── d3d9_vertex_declaration.cpp │ ├── d3d9_vertex_declaration.h │ ├── d3d9_volume.cpp │ ├── d3d9_volume.h │ ├── meson.build │ ├── shaders │ │ ├── d3d9_convert_a2w10v10u10.comp │ │ ├── d3d9_convert_common.h │ │ ├── d3d9_convert_l6v5u5.comp │ │ ├── d3d9_convert_nv12.comp │ │ ├── d3d9_convert_x8l8v8u8.comp │ │ ├── d3d9_convert_yuy2_uyvy.comp │ │ └── d3d9_convert_yv12.comp │ └── version.rc ├── dxbc │ ├── dxbc_analysis.cpp │ ├── dxbc_analysis.h │ ├── dxbc_chunk_isgn.cpp │ ├── dxbc_chunk_isgn.h │ ├── dxbc_chunk_shex.cpp │ ├── dxbc_chunk_shex.h │ ├── dxbc_common.cpp │ ├── dxbc_common.h │ ├── dxbc_compiler.cpp │ ├── dxbc_compiler.h │ ├── dxbc_decoder.cpp │ ├── dxbc_decoder.h │ ├── dxbc_defs.cpp │ ├── dxbc_defs.h │ ├── dxbc_enums.h │ ├── dxbc_header.cpp │ ├── dxbc_header.h │ ├── dxbc_include.h │ ├── dxbc_modinfo.h │ ├── dxbc_module.cpp │ ├── dxbc_module.h │ ├── dxbc_names.cpp │ ├── dxbc_names.h │ ├── dxbc_options.cpp │ ├── dxbc_options.h │ ├── dxbc_reader.cpp │ ├── dxbc_reader.h │ ├── dxbc_tag.h │ ├── dxbc_util.cpp │ ├── dxbc_util.h │ └── meson.build ├── dxgi │ ├── dxgi.def │ ├── dxgi_adapter.cpp │ ├── dxgi_adapter.h │ ├── dxgi_enums.cpp │ ├── dxgi_enums.h │ ├── dxgi_factory.cpp │ ├── dxgi_factory.h │ ├── dxgi_format.cpp │ ├── dxgi_format.h │ ├── dxgi_include.h │ ├── dxgi_interfaces.h │ ├── dxgi_main.cpp │ ├── dxgi_monitor.cpp │ ├── dxgi_monitor.h │ ├── dxgi_object.h │ ├── dxgi_options.cpp │ ├── dxgi_options.h │ ├── dxgi_output.cpp │ ├── dxgi_output.h │ ├── dxgi_swapchain.cpp │ ├── dxgi_swapchain.h │ ├── dxgi_swapchain_dispatcher.h │ ├── meson.build │ └── version.rc ├── dxso │ ├── dxso_analysis.cpp │ ├── dxso_analysis.h │ ├── dxso_code.cpp │ ├── dxso_code.h │ ├── dxso_common.cpp │ ├── dxso_common.h │ ├── dxso_compiler.cpp │ ├── dxso_compiler.h │ ├── dxso_ctab.cpp │ ├── dxso_ctab.h │ ├── dxso_decoder.cpp │ ├── dxso_decoder.h │ ├── dxso_enums.cpp │ ├── dxso_enums.h │ ├── dxso_header.cpp │ ├── dxso_header.h │ ├── dxso_helpers.h │ ├── dxso_include.h │ ├── dxso_isgn.h │ ├── dxso_modinfo.h │ ├── dxso_module.cpp │ ├── dxso_module.h │ ├── dxso_options.cpp │ ├── dxso_options.h │ ├── dxso_reader.cpp │ ├── dxso_reader.h │ ├── dxso_tables.cpp │ ├── dxso_tables.h │ ├── dxso_util.cpp │ ├── dxso_util.h │ └── meson.build ├── dxvk │ ├── dxvk_adapter.cpp │ ├── dxvk_adapter.h │ ├── dxvk_barrier.cpp │ ├── dxvk_barrier.h │ ├── dxvk_bind_mask.h │ ├── dxvk_buffer.cpp │ ├── dxvk_buffer.h │ ├── dxvk_cmdlist.cpp │ ├── dxvk_cmdlist.h │ ├── dxvk_compute.cpp │ ├── dxvk_compute.h │ ├── dxvk_constant_state.h │ ├── dxvk_context.cpp │ ├── dxvk_context.h │ ├── dxvk_context_state.h │ ├── dxvk_cs.cpp │ ├── dxvk_cs.h │ ├── dxvk_data.cpp │ ├── dxvk_data.h │ ├── dxvk_descriptor.cpp │ ├── dxvk_descriptor.h │ ├── dxvk_device.cpp │ ├── dxvk_device.h │ ├── dxvk_device_filter.cpp │ ├── dxvk_device_filter.h │ ├── dxvk_device_info.h │ ├── dxvk_extension_provider.h │ ├── dxvk_extensions.cpp │ ├── dxvk_extensions.h │ ├── dxvk_format.cpp │ ├── dxvk_format.h │ ├── dxvk_framebuffer.cpp │ ├── dxvk_framebuffer.h │ ├── dxvk_gpu_event.cpp │ ├── dxvk_gpu_event.h │ ├── dxvk_gpu_query.cpp │ ├── dxvk_gpu_query.h │ ├── dxvk_graphics.cpp │ ├── dxvk_graphics.h │ ├── dxvk_graphics_state.h │ ├── dxvk_hash.h │ ├── dxvk_image.cpp │ ├── dxvk_image.h │ ├── dxvk_include.h │ ├── dxvk_instance.cpp │ ├── dxvk_instance.h │ ├── dxvk_lifetime.cpp │ ├── dxvk_lifetime.h │ ├── dxvk_limits.h │ ├── dxvk_main.cpp │ ├── dxvk_main.h │ ├── dxvk_memory.cpp │ ├── dxvk_memory.h │ ├── dxvk_meta_blit.cpp │ ├── dxvk_meta_blit.h │ ├── dxvk_meta_clear.cpp │ ├── dxvk_meta_clear.h │ ├── dxvk_meta_copy.cpp │ ├── dxvk_meta_copy.h │ ├── dxvk_meta_mipgen.cpp │ ├── dxvk_meta_mipgen.h │ ├── dxvk_meta_pack.cpp │ ├── dxvk_meta_pack.h │ ├── dxvk_meta_resolve.cpp │ ├── dxvk_meta_resolve.h │ ├── dxvk_objects.h │ ├── dxvk_openvr.cpp │ ├── dxvk_openvr.h │ ├── dxvk_openxr.cpp │ ├── dxvk_openxr.h │ ├── dxvk_options.cpp │ ├── dxvk_options.h │ ├── dxvk_pipecache.cpp │ ├── dxvk_pipecache.h │ ├── dxvk_pipelayout.cpp │ ├── dxvk_pipelayout.h │ ├── dxvk_pipemanager.cpp │ ├── dxvk_pipemanager.h │ ├── dxvk_platform_exts.h │ ├── dxvk_queue.cpp │ ├── dxvk_queue.h │ ├── dxvk_recycler.h │ ├── dxvk_renderpass.cpp │ ├── dxvk_renderpass.h │ ├── dxvk_resource.cpp │ ├── dxvk_resource.h │ ├── dxvk_sampler.cpp │ ├── dxvk_sampler.h │ ├── dxvk_shader.cpp │ ├── dxvk_shader.h │ ├── dxvk_shader_key.cpp │ ├── dxvk_shader_key.h │ ├── dxvk_signal.cpp │ ├── dxvk_signal.h │ ├── dxvk_spec_const.cpp │ ├── dxvk_spec_const.h │ ├── dxvk_staging.cpp │ ├── dxvk_staging.h │ ├── dxvk_state_cache.cpp │ ├── dxvk_state_cache.h │ ├── dxvk_state_cache_types.h │ ├── dxvk_stats.cpp │ ├── dxvk_stats.h │ ├── dxvk_swapchain_blitter.cpp │ ├── dxvk_swapchain_blitter.h │ ├── dxvk_unbound.cpp │ ├── dxvk_unbound.h │ ├── dxvk_util.cpp │ ├── dxvk_util.h │ ├── hud │ │ ├── dxvk_hud.cpp │ │ ├── dxvk_hud.h │ │ ├── dxvk_hud_font.cpp │ │ ├── dxvk_hud_font.h │ │ ├── dxvk_hud_item.cpp │ │ ├── dxvk_hud_item.h │ │ ├── dxvk_hud_renderer.cpp │ │ ├── dxvk_hud_renderer.h │ │ └── shaders │ │ │ ├── hud_line_frag.frag │ │ │ ├── hud_line_vert.vert │ │ │ ├── hud_text_frag.frag │ │ │ └── hud_text_vert.vert │ ├── meson.build │ ├── platform │ │ └── dxvk_win32_exts.cpp │ └── shaders │ │ ├── dxvk_blit_frag_1d.frag │ │ ├── dxvk_blit_frag_2d.frag │ │ ├── dxvk_blit_frag_3d.frag │ │ ├── dxvk_clear_buffer_f.comp │ │ ├── dxvk_clear_buffer_u.comp │ │ ├── dxvk_clear_image1d_f.comp │ │ ├── dxvk_clear_image1d_u.comp │ │ ├── dxvk_clear_image1darr_f.comp │ │ ├── dxvk_clear_image1darr_u.comp │ │ ├── dxvk_clear_image2d_f.comp │ │ ├── dxvk_clear_image2d_u.comp │ │ ├── dxvk_clear_image2darr_f.comp │ │ ├── dxvk_clear_image2darr_u.comp │ │ ├── dxvk_clear_image3d_f.comp │ │ ├── dxvk_clear_image3d_u.comp │ │ ├── dxvk_copy_buffer_image.comp │ │ ├── dxvk_copy_color_1d.frag │ │ ├── dxvk_copy_color_2d.frag │ │ ├── dxvk_copy_color_ms.frag │ │ ├── dxvk_copy_depth_1d.frag │ │ ├── dxvk_copy_depth_2d.frag │ │ ├── dxvk_copy_depth_ms.frag │ │ ├── dxvk_copy_depth_stencil_1d.frag │ │ ├── dxvk_copy_depth_stencil_2d.frag │ │ ├── dxvk_copy_depth_stencil_ms.frag │ │ ├── dxvk_fullscreen_geom.geom │ │ ├── dxvk_fullscreen_layer_vert.vert │ │ ├── dxvk_fullscreen_vert.vert │ │ ├── dxvk_pack_d24s8.comp │ │ ├── dxvk_pack_d32s8.comp │ │ ├── dxvk_present_frag.frag │ │ ├── dxvk_present_frag_blit.frag │ │ ├── dxvk_present_frag_ms.frag │ │ ├── dxvk_present_frag_ms_amd.frag │ │ ├── dxvk_present_vert.vert │ │ ├── dxvk_resolve_frag_d.frag │ │ ├── dxvk_resolve_frag_ds.frag │ │ ├── dxvk_resolve_frag_f.frag │ │ ├── dxvk_resolve_frag_f_amd.frag │ │ ├── dxvk_resolve_frag_i.frag │ │ ├── dxvk_resolve_frag_u.frag │ │ ├── dxvk_unpack_d24s8.comp │ │ ├── dxvk_unpack_d24s8_as_d32s8.comp │ │ └── dxvk_unpack_d32s8.comp ├── dxvk_config │ ├── dxvk_config.cpp │ ├── dxvk_config.def │ ├── dxvk_config.h │ ├── dxvk_config.spec │ ├── meson.build │ └── version.rc ├── meson.build ├── spirv │ ├── meson.build │ ├── spirv_code_buffer.cpp │ ├── spirv_code_buffer.h │ ├── spirv_compression.cpp │ ├── spirv_compression.h │ ├── spirv_include.h │ ├── spirv_instruction.h │ ├── spirv_module.cpp │ └── spirv_module.h ├── util │ ├── com │ │ ├── com_guid.cpp │ │ ├── com_guid.h │ │ ├── com_include.h │ │ ├── com_object.h │ │ ├── com_pointer.h │ │ ├── com_private_data.cpp │ │ └── com_private_data.h │ ├── config │ │ ├── config.cpp │ │ └── config.h │ ├── log │ │ ├── log.cpp │ │ ├── log.h │ │ ├── log_debug.cpp │ │ └── log_debug.h │ ├── meson.build │ ├── rc │ │ ├── util_rc.h │ │ └── util_rc_ptr.h │ ├── sha1 │ │ ├── sha1.c │ │ ├── sha1.h │ │ ├── sha1_util.cpp │ │ └── sha1_util.h │ ├── sync │ │ ├── sync_recursive.cpp │ │ ├── sync_recursive.h │ │ ├── sync_signal.h │ │ ├── sync_spinlock.h │ │ └── sync_ticketlock.h │ ├── thread.h │ ├── util_bit.h │ ├── util_enum.h │ ├── util_env.cpp │ ├── util_env.h │ ├── util_error.h │ ├── util_flags.h │ ├── util_fps_limiter.cpp │ ├── util_fps_limiter.h │ ├── util_gdi.cpp │ ├── util_gdi.h │ ├── util_lazy.h │ ├── util_likely.h │ ├── util_luid.cpp │ ├── util_luid.h │ ├── util_math.h │ ├── util_matrix.cpp │ ├── util_matrix.h │ ├── util_monitor.cpp │ ├── util_monitor.h │ ├── util_ratio.h │ ├── util_small_vector.h │ ├── util_string.cpp │ ├── util_string.h │ ├── util_time.h │ └── util_vector.h └── vulkan │ ├── meson.build │ ├── vulkan_loader.cpp │ ├── vulkan_loader.h │ ├── vulkan_names.cpp │ ├── vulkan_names.h │ ├── vulkan_presenter.cpp │ ├── vulkan_presenter.h │ └── vulkan_util.h ├── tests ├── d3d11 │ ├── meson.build │ ├── test_d3d11_compute.cpp │ ├── test_d3d11_formats.cpp │ ├── test_d3d11_map_read.cpp │ ├── test_d3d11_streamout.cpp │ ├── test_d3d11_triangle.cpp │ ├── test_d3d11_video.cpp │ └── video_image.raw ├── d3d9 │ ├── meson.build │ ├── test_d3d9_bc_update_surface.cpp │ ├── test_d3d9_buffer.cpp │ ├── test_d3d9_clear.cpp │ ├── test_d3d9_l6v5u5.cpp │ ├── test_d3d9_nv12.cpp │ ├── test_d3d9_nv12.yuv.h │ ├── test_d3d9_triangle.cpp │ └── test_d3d9_up.cpp ├── dxbc │ ├── meson.build │ ├── test_dxbc_compiler.cpp │ ├── test_dxbc_disasm.cpp │ └── test_hlsl_compiler.cpp ├── dxgi │ ├── meson.build │ └── test_dxgi_factory.cpp ├── meson.build └── test_utils.h └── version.h.in /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Report crashes, rendering issues etc. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Please describe your issue as accurately as possible. If you run into a problem with a binary release, make sure to test with latest `master` as well. 11 | 12 | **Important:** When reporting an issue with a specific game or application, such as crashes or rendering issues, please include log files and, if possible, a D3D11/D3D9 Apitrace (see https://github.com/apitrace/apitrace) so that the issue can be reproduced. 13 | In order to create a trace for **D3D11/D3D10**: Run `wine apitrace.exe trace -a dxgi YOURGAME.exe`. 14 | In order to create a trace for **D3D9**: Follow https://github.com/Joshua-Ashton/d9vk/wiki/Making-a-Trace. 15 | Preferably record the trace on Windows, or wined3d if possible. 16 | 17 | **Reports with no log files will be ignored.** 18 | 19 | ### Software information 20 | Name of the game, settings used etc. 21 | 22 | ### System information 23 | - GPU: 24 | - Driver: 25 | - Wine version: 26 | - DXVK version: 27 | 28 | ### Apitrace file(s) 29 | - Put a link here 30 | 31 | ### Log files 32 | - d3d9.log: 33 | - d3d11.log: 34 | - dxgi.log: 35 | -------------------------------------------------------------------------------- /.github/workflows/artifacts.yml: -------------------------------------------------------------------------------- 1 | name: Artifacts (Package) 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | jobs: 6 | build-artifacts: 7 | runs-on: ubuntu-20.04 8 | 9 | steps: 10 | - name: Checkout code 11 | id: checkout-code 12 | uses: actions/checkout@v2 13 | with: 14 | submodules: recursive 15 | fetch-depth: 0 16 | 17 | - name: Setup problem matcher 18 | uses: Joshua-Ashton/gcc-problem-matcher@v1 19 | 20 | - name: Build release 21 | id: build-release 22 | uses: Joshua-Ashton/arch-mingw-github-action@v5 23 | with: 24 | command: | 25 | export VERSION_NAME="${GITHUB_REF##*/}-${GITHUB_SHA##*/}" 26 | ./package-release.sh ${VERSION_NAME} build --no-package 27 | echo "VERSION_NAME=${VERSION_NAME}" >> $GITHUB_ENV 28 | 29 | - name: Upload artifacts 30 | id: upload-artifacts 31 | uses: actions/upload-artifact@v2 32 | with: 33 | name: dxvk-${{ env.VERSION_NAME }} 34 | path: build/dxvk-${{ env.VERSION_NAME }} 35 | if-no-files-found: error 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017-2021 Philip Rebohle 2 | Copyright (c) 2019-2021 Joshua Ashton 3 | 4 | zlib/libpng license 5 | 6 | This software is provided 'as-is', without any express or implied 7 | warranty. In no event will the authors be held liable for any damages 8 | arising from the use of this software. 9 | 10 | Permission is granted to anyone to use this software for any purpose, 11 | including commercial applications, and to alter it and redistribute it 12 | freely, subject to the following restrictions: 13 | 14 | – The origin of this software must not be misrepresented; you must not 15 | claim that you wrote the original software. If you use this software 16 | in a product, an acknowledgment in the product documentation would be 17 | appreciated but is not required. 18 | 19 | – Altered source versions must be plainly marked as such, and must not 20 | be misrepresented as being the original software. 21 | 22 | – This notice may not be removed or altered from any source distribution. 23 | -------------------------------------------------------------------------------- /RELEASE: -------------------------------------------------------------------------------- 1 | 1.9.2 2 | -------------------------------------------------------------------------------- /build-win32.txt: -------------------------------------------------------------------------------- 1 | [binaries] 2 | c = 'i686-w64-mingw32-gcc' 3 | cpp = 'i686-w64-mingw32-g++' 4 | ar = 'i686-w64-mingw32-ar' 5 | strip = 'i686-w64-mingw32-strip' 6 | windres = 'i686-w64-mingw32-windres' 7 | 8 | [properties] 9 | needs_exe_wrapper = true 10 | 11 | [host_machine] 12 | system = 'windows' 13 | cpu_family = 'x86' 14 | cpu = 'x86' 15 | endian = 'little' 16 | -------------------------------------------------------------------------------- /build-win64.txt: -------------------------------------------------------------------------------- 1 | [binaries] 2 | c = 'x86_64-w64-mingw32-gcc' 3 | cpp = 'x86_64-w64-mingw32-g++' 4 | ar = 'x86_64-w64-mingw32-ar' 5 | strip = 'x86_64-w64-mingw32-strip' 6 | windres = 'x86_64-w64-mingw32-windres' 7 | 8 | [properties] 9 | needs_exe_wrapper = true 10 | 11 | [host_machine] 12 | system = 'windows' 13 | cpu_family = 'x86_64' 14 | cpu = 'x86_64' 15 | endian = 'little' 16 | -------------------------------------------------------------------------------- /include/openvr/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Valve Corporation 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its contributors 15 | may be used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /lib/d3dcompiler_43.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValveSoftware/dxvk/78ef4cfd92cb7f448292aaca83091914ab271257/lib/d3dcompiler_43.lib -------------------------------------------------------------------------------- /lib/libd3dcompiler_43.def: -------------------------------------------------------------------------------- 1 | ; File generated automatically from d3dcompiler_43.spec; do not edit! 2 | 3 | LIBRARY d3dcompiler_43.dll 4 | 5 | EXPORTS 6 | D3DAssemble @1 7 | D3DCompile @3 8 | D3DCreateBlob @5 9 | D3DDisassemble @8 10 | D3DGetBlobPart @9 11 | D3DGetDebugInfo @10 12 | D3DGetInputAndOutputSignatureBlob @11 13 | D3DGetInputSignatureBlob @12 14 | D3DGetOutputSignatureBlob @13 15 | D3DPreprocess @14 16 | D3DReflect @15 17 | D3DStripShader @17 18 | -------------------------------------------------------------------------------- /lib/vulkan-1.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValveSoftware/dxvk/78ef4cfd92cb7f448292aaca83091914ab271257/lib/vulkan-1.lib -------------------------------------------------------------------------------- /lib32/d3dcompiler_43.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValveSoftware/dxvk/78ef4cfd92cb7f448292aaca83091914ab271257/lib32/d3dcompiler_43.lib -------------------------------------------------------------------------------- /lib32/libd3dcompiler_43.def: -------------------------------------------------------------------------------- 1 | ; File generated automatically from d3dcompiler_43.spec; do not edit! 2 | 3 | LIBRARY d3dcompiler_43.dll 4 | 5 | EXPORTS 6 | D3DAssemble@32 @1 7 | D3DCompile@44 @3 8 | D3DCreateBlob@8 @5 9 | D3DDisassemble@20 @8 10 | D3DGetBlobPart@20 @9 11 | D3DGetDebugInfo@12 @10 12 | D3DGetInputAndOutputSignatureBlob@12 @11 13 | D3DGetInputSignatureBlob@12 @12 14 | D3DGetOutputSignatureBlob@12 @13 15 | D3DPreprocess@28 @14 16 | D3DReflect@16 @15 17 | D3DStripShader@16 @17 18 | -------------------------------------------------------------------------------- /lib32/vulkan-1.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValveSoftware/dxvk/78ef4cfd92cb7f448292aaca83091914ab271257/lib32/vulkan-1.lib -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('enable_tests', type : 'boolean', value : false) 2 | option('enable_dxgi', type : 'boolean', value : true, description: 'Build DXGI') 3 | option('enable_d3d9', type : 'boolean', value : true, description: 'Build D3D9') 4 | option('enable_d3d10', type : 'boolean', value : true, description: 'Build D3D10') 5 | option('enable_d3d11', type : 'boolean', value : true, description: 'Build D3D11') 6 | option('build_id', type : 'boolean', value : false) 7 | -------------------------------------------------------------------------------- /src/d3d10/d3d10.def: -------------------------------------------------------------------------------- 1 | LIBRARY D3D10.DLL 2 | EXPORTS 3 | D3D10CreateDevice 4 | D3D10CreateDeviceAndSwapChain 5 | D3D10GetVertexShaderProfile 6 | D3D10GetGeometryShaderProfile 7 | D3D10GetPixelShaderProfile 8 | D3D10CreateBlob 9 | D3D10GetInputSignatureBlob 10 | D3D10GetOutputSignatureBlob 11 | D3D10ReflectShader 12 | D3D10CompileShader 13 | D3D10CreateEffectFromMemory 14 | D3D10CreateEffectPoolFromMemory 15 | D3D10CompileEffectFromMemory 16 | D3D10DisassembleEffect 17 | D3D10DisassembleShader 18 | D3D10PreprocessShader 19 | D3D10CreateStateBlock 20 | D3D10StateBlockMaskDifference 21 | D3D10StateBlockMaskDisableAll 22 | D3D10StateBlockMaskDisableCapture 23 | D3D10StateBlockMaskEnableAll 24 | D3D10StateBlockMaskEnableCapture 25 | D3D10StateBlockMaskGetSetting 26 | D3D10StateBlockMaskIntersect 27 | D3D10StateBlockMaskUnion 28 | D3D10GetVersion 29 | D3D10RegisterLayers 30 | -------------------------------------------------------------------------------- /src/d3d10/d3d10_1.def: -------------------------------------------------------------------------------- 1 | LIBRARY D3D10_1.DLL 2 | EXPORTS 3 | D3D10CreateDevice1 4 | D3D10CreateDeviceAndSwapChain1 5 | D3D10GetVertexShaderProfile 6 | D3D10GetGeometryShaderProfile 7 | D3D10GetPixelShaderProfile 8 | D3D10CreateBlob 9 | D3D10GetInputSignatureBlob 10 | D3D10GetOutputSignatureBlob 11 | D3D10ReflectShader 12 | D3D10CompileShader 13 | D3D10CreateEffectFromMemory 14 | D3D10CreateEffectPoolFromMemory 15 | D3D10CompileEffectFromMemory 16 | D3D10DisassembleEffect 17 | D3D10DisassembleShader 18 | D3D10PreprocessShader 19 | D3D10CreateStateBlock 20 | D3D10StateBlockMaskDifference 21 | D3D10StateBlockMaskDisableAll 22 | D3D10StateBlockMaskDisableCapture 23 | D3D10StateBlockMaskEnableAll 24 | D3D10StateBlockMaskEnableCapture 25 | D3D10StateBlockMaskGetSetting 26 | D3D10StateBlockMaskIntersect 27 | D3D10StateBlockMaskUnion 28 | D3D10GetVersion 29 | D3D10RegisterLayers -------------------------------------------------------------------------------- /src/d3d10/d3d10_blend.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d10_util.h" 4 | 5 | namespace dxvk { 6 | 7 | class D3D11BlendState; 8 | class D3D11Device; 9 | 10 | class D3D10BlendState : public ID3D10BlendState1 { 11 | 12 | public: 13 | 14 | D3D10BlendState(D3D11BlendState* pParent) 15 | : m_d3d11(pParent) { } 16 | 17 | HRESULT STDMETHODCALLTYPE QueryInterface( 18 | REFIID riid, 19 | void** ppvObject); 20 | 21 | ULONG STDMETHODCALLTYPE AddRef(); 22 | 23 | ULONG STDMETHODCALLTYPE Release(); 24 | 25 | void STDMETHODCALLTYPE GetDevice( 26 | ID3D10Device** ppDevice); 27 | 28 | HRESULT STDMETHODCALLTYPE GetPrivateData( 29 | REFGUID guid, 30 | UINT* pDataSize, 31 | void* pData); 32 | 33 | HRESULT STDMETHODCALLTYPE SetPrivateData( 34 | REFGUID guid, 35 | UINT DataSize, 36 | const void* pData); 37 | 38 | HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( 39 | REFGUID guid, 40 | const IUnknown* pData); 41 | 42 | void STDMETHODCALLTYPE GetDesc( 43 | D3D10_BLEND_DESC* pDesc); 44 | 45 | void STDMETHODCALLTYPE GetDesc1( 46 | D3D10_BLEND_DESC1* pDesc); 47 | 48 | D3D11BlendState* GetD3D11Iface() { 49 | return m_d3d11; 50 | } 51 | 52 | private: 53 | 54 | D3D11BlendState* m_d3d11; 55 | 56 | }; 57 | 58 | } -------------------------------------------------------------------------------- /src/d3d10/d3d10_depth_stencil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d10_util.h" 4 | 5 | namespace dxvk { 6 | 7 | class D3D11DepthStencilState; 8 | class D3D11Device; 9 | 10 | class D3D10DepthStencilState : public ID3D10DepthStencilState { 11 | 12 | public: 13 | 14 | D3D10DepthStencilState(D3D11DepthStencilState* pParent) 15 | : m_d3d11(pParent) { } 16 | 17 | HRESULT STDMETHODCALLTYPE QueryInterface( 18 | REFIID riid, 19 | void** ppvObject); 20 | 21 | ULONG STDMETHODCALLTYPE AddRef(); 22 | 23 | ULONG STDMETHODCALLTYPE Release(); 24 | 25 | void STDMETHODCALLTYPE GetDevice( 26 | ID3D10Device** ppDevice); 27 | 28 | HRESULT STDMETHODCALLTYPE GetPrivateData( 29 | REFGUID guid, 30 | UINT* pDataSize, 31 | void* pData); 32 | 33 | HRESULT STDMETHODCALLTYPE SetPrivateData( 34 | REFGUID guid, 35 | UINT DataSize, 36 | const void* pData); 37 | 38 | HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( 39 | REFGUID guid, 40 | const IUnknown* pData); 41 | 42 | void STDMETHODCALLTYPE GetDesc( 43 | D3D10_DEPTH_STENCIL_DESC* pDesc); 44 | 45 | D3D11DepthStencilState* GetD3D11Iface() { 46 | return m_d3d11; 47 | } 48 | 49 | private: 50 | 51 | D3D11DepthStencilState* m_d3d11; 52 | 53 | }; 54 | 55 | } -------------------------------------------------------------------------------- /src/d3d10/d3d10_include.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../dxgi/dxgi_include.h" 4 | 5 | #include "../util/sync/sync_spinlock.h" 6 | #include "../util/sync/sync_recursive.h" 7 | 8 | #include 9 | #include 10 | -------------------------------------------------------------------------------- /src/d3d10/d3d10_input_layout.cpp: -------------------------------------------------------------------------------- 1 | #include "d3d10_input_layout.h" 2 | 3 | #include "../d3d11/d3d11_device.h" 4 | #include "../d3d11/d3d11_input_layout.h" 5 | 6 | namespace dxvk { 7 | 8 | HRESULT STDMETHODCALLTYPE D3D10InputLayout::QueryInterface( 9 | REFIID riid, 10 | void** ppvObject) { 11 | return m_d3d11->QueryInterface(riid, ppvObject); 12 | } 13 | 14 | 15 | ULONG STDMETHODCALLTYPE D3D10InputLayout::AddRef() { 16 | return m_d3d11->AddRef(); 17 | } 18 | 19 | 20 | ULONG STDMETHODCALLTYPE D3D10InputLayout::Release() { 21 | return m_d3d11->Release(); 22 | } 23 | 24 | 25 | void STDMETHODCALLTYPE D3D10InputLayout::GetDevice( 26 | ID3D10Device** ppDevice) { 27 | GetD3D10Device(m_d3d11, ppDevice); 28 | } 29 | 30 | 31 | HRESULT STDMETHODCALLTYPE D3D10InputLayout::GetPrivateData( 32 | REFGUID guid, 33 | UINT* pDataSize, 34 | void* pData) { 35 | return m_d3d11->GetPrivateData(guid, pDataSize, pData); 36 | } 37 | 38 | 39 | HRESULT STDMETHODCALLTYPE D3D10InputLayout::SetPrivateData( 40 | REFGUID guid, 41 | UINT DataSize, 42 | const void* pData) { 43 | return m_d3d11->SetPrivateData(guid, DataSize, pData); 44 | } 45 | 46 | 47 | HRESULT STDMETHODCALLTYPE D3D10InputLayout::SetPrivateDataInterface( 48 | REFGUID guid, 49 | const IUnknown* pData) { 50 | return m_d3d11->SetPrivateDataInterface(guid, pData); 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /src/d3d10/d3d10_input_layout.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d10_util.h" 4 | 5 | namespace dxvk { 6 | 7 | class D3D11Device; 8 | class D3D11InputLayout; 9 | 10 | class D3D10InputLayout : public ID3D10InputLayout { 11 | 12 | public: 13 | 14 | D3D10InputLayout(D3D11InputLayout* pParent) 15 | : m_d3d11(pParent) { } 16 | 17 | HRESULT STDMETHODCALLTYPE QueryInterface( 18 | REFIID riid, 19 | void** ppvObject); 20 | 21 | ULONG STDMETHODCALLTYPE AddRef(); 22 | 23 | ULONG STDMETHODCALLTYPE Release(); 24 | 25 | void STDMETHODCALLTYPE GetDevice( 26 | ID3D10Device** ppDevice); 27 | 28 | HRESULT STDMETHODCALLTYPE GetPrivateData( 29 | REFGUID guid, 30 | UINT* pDataSize, 31 | void* pData); 32 | 33 | HRESULT STDMETHODCALLTYPE SetPrivateData( 34 | REFGUID guid, 35 | UINT DataSize, 36 | const void* pData); 37 | 38 | HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( 39 | REFGUID guid, 40 | const IUnknown* pData); 41 | 42 | D3D11InputLayout* GetD3D11Iface() { 43 | return m_d3d11; 44 | } 45 | 46 | private: 47 | 48 | D3D11InputLayout* m_d3d11; 49 | 50 | }; 51 | 52 | } -------------------------------------------------------------------------------- /src/d3d10/d3d10_interfaces.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d10_include.h" 4 | 5 | #ifdef _MSC_VER 6 | struct __declspec(uuid("0803425a-57f5-4dd6-9465-a87570834a08")) ID3D10StateBlock; 7 | #else 8 | __CRT_UUID_DECL(ID3D10StateBlock, 0x0803425a,0x57f5,0x4dd6,0x94,0x65,0xa8,0x75,0x70,0x83,0x4a,0x08); 9 | #endif 10 | -------------------------------------------------------------------------------- /src/d3d10/d3d10_multithread.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "d3d10_device.h" 4 | 5 | namespace dxvk { 6 | 7 | D3D10Multithread::D3D10Multithread( 8 | IUnknown* pParent, 9 | BOOL Protected) 10 | : m_parent (pParent), 11 | m_protected (Protected) { 12 | 13 | } 14 | 15 | 16 | D3D10Multithread::~D3D10Multithread() { 17 | 18 | } 19 | 20 | 21 | ULONG STDMETHODCALLTYPE D3D10Multithread::AddRef() { 22 | return m_parent->AddRef(); 23 | } 24 | 25 | 26 | ULONG STDMETHODCALLTYPE D3D10Multithread::Release() { 27 | return m_parent->Release(); 28 | } 29 | 30 | 31 | HRESULT STDMETHODCALLTYPE D3D10Multithread::QueryInterface( 32 | REFIID riid, 33 | void** ppvObject) { 34 | return m_parent->QueryInterface(riid, ppvObject); 35 | } 36 | 37 | 38 | void STDMETHODCALLTYPE D3D10Multithread::Enter() { 39 | if (m_protected) 40 | m_mutex.lock(); 41 | } 42 | 43 | 44 | void STDMETHODCALLTYPE D3D10Multithread::Leave() { 45 | if (m_protected) 46 | m_mutex.unlock(); 47 | } 48 | 49 | 50 | BOOL STDMETHODCALLTYPE D3D10Multithread::SetMultithreadProtected( 51 | BOOL bMTProtect) { 52 | return std::exchange(m_protected, bMTProtect); 53 | } 54 | 55 | 56 | BOOL STDMETHODCALLTYPE D3D10Multithread::GetMultithreadProtected() { 57 | return m_protected; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/d3d10/d3d10_rasterizer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d10_util.h" 4 | 5 | namespace dxvk { 6 | 7 | class D3D11RasterizerState; 8 | class D3D11Device; 9 | 10 | class D3D10RasterizerState : public ID3D10RasterizerState { 11 | 12 | public: 13 | 14 | D3D10RasterizerState(D3D11RasterizerState* pParent) 15 | : m_d3d11(pParent) { } 16 | 17 | HRESULT STDMETHODCALLTYPE QueryInterface( 18 | REFIID riid, 19 | void** ppvObject); 20 | 21 | ULONG STDMETHODCALLTYPE AddRef(); 22 | 23 | ULONG STDMETHODCALLTYPE Release(); 24 | 25 | void STDMETHODCALLTYPE GetDevice( 26 | ID3D10Device** ppDevice); 27 | 28 | HRESULT STDMETHODCALLTYPE GetPrivateData( 29 | REFGUID guid, 30 | UINT* pDataSize, 31 | void* pData); 32 | 33 | HRESULT STDMETHODCALLTYPE SetPrivateData( 34 | REFGUID guid, 35 | UINT DataSize, 36 | const void* pData); 37 | 38 | HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( 39 | REFGUID guid, 40 | const IUnknown* pData); 41 | 42 | void STDMETHODCALLTYPE GetDesc( 43 | D3D10_RASTERIZER_DESC* pDesc); 44 | 45 | D3D11RasterizerState* GetD3D11Iface() { 46 | return m_d3d11; 47 | } 48 | 49 | private: 50 | 51 | D3D11RasterizerState* m_d3d11; 52 | 53 | }; 54 | 55 | } -------------------------------------------------------------------------------- /src/d3d10/d3d10_sampler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d10_util.h" 4 | 5 | namespace dxvk { 6 | 7 | class D3D11Device; 8 | class D3D11SamplerState; 9 | 10 | class D3D10SamplerState : public ID3D10SamplerState { 11 | 12 | public: 13 | 14 | D3D10SamplerState(D3D11SamplerState* pParent) 15 | : m_d3d11(pParent) { } 16 | 17 | HRESULT STDMETHODCALLTYPE QueryInterface( 18 | REFIID riid, 19 | void** ppvObject); 20 | 21 | ULONG STDMETHODCALLTYPE AddRef(); 22 | 23 | ULONG STDMETHODCALLTYPE Release(); 24 | 25 | void STDMETHODCALLTYPE GetDevice( 26 | ID3D10Device** ppDevice); 27 | 28 | HRESULT STDMETHODCALLTYPE GetPrivateData( 29 | REFGUID guid, 30 | UINT* pDataSize, 31 | void* pData); 32 | 33 | HRESULT STDMETHODCALLTYPE SetPrivateData( 34 | REFGUID guid, 35 | UINT DataSize, 36 | const void* pData); 37 | 38 | HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( 39 | REFGUID guid, 40 | const IUnknown* pData); 41 | 42 | void STDMETHODCALLTYPE GetDesc( 43 | D3D10_SAMPLER_DESC* pDesc); 44 | 45 | D3D11SamplerState* GetD3D11Iface() { 46 | return m_d3d11; 47 | } 48 | 49 | private: 50 | 51 | D3D11SamplerState* m_d3d11; 52 | 53 | }; 54 | 55 | } -------------------------------------------------------------------------------- /src/d3d10/d3d10_view_dsv.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d10_util.h" 4 | 5 | namespace dxvk { 6 | 7 | class D3D11Device; 8 | class D3D11DepthStencilView; 9 | 10 | class D3D10DepthStencilView : public ID3D10DepthStencilView { 11 | 12 | public: 13 | 14 | D3D10DepthStencilView(D3D11DepthStencilView* pParent) 15 | : m_d3d11(pParent) { } 16 | 17 | HRESULT STDMETHODCALLTYPE QueryInterface( 18 | REFIID riid, 19 | void** ppvObject); 20 | 21 | ULONG STDMETHODCALLTYPE AddRef(); 22 | 23 | ULONG STDMETHODCALLTYPE Release(); 24 | 25 | void STDMETHODCALLTYPE GetDevice( 26 | ID3D10Device** ppDevice); 27 | 28 | HRESULT STDMETHODCALLTYPE GetPrivateData( 29 | REFGUID guid, 30 | UINT* pDataSize, 31 | void* pData); 32 | 33 | HRESULT STDMETHODCALLTYPE SetPrivateData( 34 | REFGUID guid, 35 | UINT DataSize, 36 | const void* pData); 37 | 38 | HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( 39 | REFGUID guid, 40 | const IUnknown* pData); 41 | 42 | void STDMETHODCALLTYPE GetResource( 43 | ID3D10Resource** ppResource); 44 | 45 | void STDMETHODCALLTYPE GetDesc( 46 | D3D10_DEPTH_STENCIL_VIEW_DESC* pDesc); 47 | 48 | D3D11DepthStencilView* GetD3D11Iface() { 49 | return m_d3d11; 50 | } 51 | 52 | private: 53 | 54 | D3D11DepthStencilView* m_d3d11; 55 | 56 | }; 57 | 58 | } -------------------------------------------------------------------------------- /src/d3d10/d3d10_view_rtv.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d10_util.h" 4 | 5 | namespace dxvk { 6 | 7 | class D3D11Device; 8 | class D3D11RenderTargetView; 9 | 10 | class D3D10RenderTargetView : public ID3D10RenderTargetView { 11 | 12 | public: 13 | 14 | D3D10RenderTargetView(D3D11RenderTargetView* pParent) 15 | : m_d3d11(pParent) { } 16 | 17 | HRESULT STDMETHODCALLTYPE QueryInterface( 18 | REFIID riid, 19 | void** ppvObject); 20 | 21 | ULONG STDMETHODCALLTYPE AddRef(); 22 | 23 | ULONG STDMETHODCALLTYPE Release(); 24 | 25 | void STDMETHODCALLTYPE GetDevice( 26 | ID3D10Device** ppDevice); 27 | 28 | HRESULT STDMETHODCALLTYPE GetPrivateData( 29 | REFGUID guid, 30 | UINT* pDataSize, 31 | void* pData); 32 | 33 | HRESULT STDMETHODCALLTYPE SetPrivateData( 34 | REFGUID guid, 35 | UINT DataSize, 36 | const void* pData); 37 | 38 | HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( 39 | REFGUID guid, 40 | const IUnknown* pData); 41 | 42 | void STDMETHODCALLTYPE GetResource( 43 | ID3D10Resource** ppResource); 44 | 45 | void STDMETHODCALLTYPE GetDesc( 46 | D3D10_RENDER_TARGET_VIEW_DESC* pDesc); 47 | 48 | D3D11RenderTargetView* GetD3D11Iface() { 49 | return m_d3d11; 50 | } 51 | 52 | private: 53 | 54 | D3D11RenderTargetView* m_d3d11; 55 | 56 | }; 57 | 58 | } -------------------------------------------------------------------------------- /src/d3d10/d3d10core.def: -------------------------------------------------------------------------------- 1 | LIBRARY D3D10CORE.DLL 2 | EXPORTS 3 | D3D10CoreCreateDevice 4 | D3D10CoreGetVersion 5 | D3D10CoreRegisterLayers 6 | -------------------------------------------------------------------------------- /src/d3d10/version10.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // DLL version information. 4 | VS_VERSION_INFO VERSIONINFO 5 | FILEVERSION 10,0,17763,1 6 | PRODUCTVERSION 10,0,17763,1 7 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 8 | FILEFLAGS 0 9 | FILEOS VOS_NT_WINDOWS32 10 | FILETYPE VFT_DLL 11 | FILESUBTYPE VFT2_UNKNOWN 12 | BEGIN 13 | BLOCK "StringFileInfo" 14 | BEGIN 15 | BLOCK "080904b0" 16 | BEGIN 17 | VALUE "CompanyName", "DXVK" 18 | VALUE "FileDescription", "Direct3D 10 Runtime" 19 | VALUE "FileVersion", "10.0.17763.1 (WinBuild.160101.0800)" 20 | VALUE "InternalName", "D3D10.dll" 21 | VALUE "LegalCopyright", "zlib/libpng license" 22 | VALUE "OriginalFilename", "D3D10.dll" 23 | VALUE "ProductName", "DXVK" 24 | VALUE "ProductVersion", "10.0.17763.1" 25 | END 26 | END 27 | BLOCK "VarFileInfo" 28 | BEGIN 29 | VALUE "Translation", 0x0809, 1200 30 | END 31 | END 32 | 33 | -------------------------------------------------------------------------------- /src/d3d10/version10_1.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // DLL version information. 4 | VS_VERSION_INFO VERSIONINFO 5 | FILEVERSION 10,0,17763,1 6 | PRODUCTVERSION 10,0,17763,1 7 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 8 | FILEFLAGS 0 9 | FILEOS VOS_NT_WINDOWS32 10 | FILETYPE VFT_DLL 11 | FILESUBTYPE VFT2_UNKNOWN 12 | BEGIN 13 | BLOCK "StringFileInfo" 14 | BEGIN 15 | BLOCK "080904b0" 16 | BEGIN 17 | VALUE "CompanyName", "DXVK" 18 | VALUE "FileDescription", "Direct3D 10.1 Runtime" 19 | VALUE "FileVersion", "10.0.17763.1 (WinBuild.160101.0800)" 20 | VALUE "InternalName", "D3D10_1.dll" 21 | VALUE "LegalCopyright", "zlib/libpng license" 22 | VALUE "OriginalFilename", "D3D10_1.dll" 23 | VALUE "ProductName", "DXVK" 24 | VALUE "ProductVersion", "10.0.17763.1" 25 | END 26 | END 27 | BLOCK "VarFileInfo" 28 | BEGIN 29 | VALUE "Translation", 0x0809, 1200 30 | END 31 | END 32 | 33 | -------------------------------------------------------------------------------- /src/d3d10/version10_core.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // DLL version information. 4 | VS_VERSION_INFO VERSIONINFO 5 | FILEVERSION 10,0,17763,1 6 | PRODUCTVERSION 10,0,17763,1 7 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 8 | FILEFLAGS 0 9 | FILEOS VOS_NT_WINDOWS32 10 | FILETYPE VFT_DLL 11 | FILESUBTYPE VFT2_UNKNOWN 12 | BEGIN 13 | BLOCK "StringFileInfo" 14 | BEGIN 15 | BLOCK "080904b0" 16 | BEGIN 17 | VALUE "CompanyName", "DXVK" 18 | VALUE "FileDescription", "Direct3D 10 Runtime" 19 | VALUE "FileVersion", "10.0.17763.1 (WinBuild.160101.0800)" 20 | VALUE "InternalName", "D3D10Core.dll" 21 | VALUE "LegalCopyright", "zlib/libpng license" 22 | VALUE "OriginalFilename", "D3D10Core.dll" 23 | VALUE "ProductName", "DXVK" 24 | VALUE "ProductVersion", "10.0.17763.1" 25 | END 26 | END 27 | BLOCK "VarFileInfo" 28 | BEGIN 29 | VALUE "Translation", 0x0809, 1200 30 | END 31 | END 32 | 33 | -------------------------------------------------------------------------------- /src/d3d11/d3d11.def: -------------------------------------------------------------------------------- 1 | LIBRARY D3D11.DLL 2 | EXPORTS 3 | D3D11CoreCreateDevice @18 4 | D3D11CreateDevice @22 5 | D3D11CreateDeviceAndSwapChain @23 6 | -------------------------------------------------------------------------------- /src/d3d11/d3d11_annotation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d11_include.h" 4 | 5 | namespace dxvk { 6 | 7 | class D3D11DeviceContext; 8 | 9 | class D3D11UserDefinedAnnotation : ID3DUserDefinedAnnotation { 10 | 11 | public: 12 | 13 | D3D11UserDefinedAnnotation(D3D11DeviceContext* ctx); 14 | ~D3D11UserDefinedAnnotation(); 15 | 16 | ULONG STDMETHODCALLTYPE AddRef(); 17 | 18 | ULONG STDMETHODCALLTYPE Release(); 19 | 20 | HRESULT STDMETHODCALLTYPE QueryInterface( 21 | REFIID riid, 22 | void** ppvObject); 23 | 24 | INT STDMETHODCALLTYPE BeginEvent( 25 | LPCWSTR Name); 26 | 27 | INT STDMETHODCALLTYPE EndEvent(); 28 | 29 | void STDMETHODCALLTYPE SetMarker( 30 | LPCWSTR Name); 31 | 32 | BOOL STDMETHODCALLTYPE GetStatus(); 33 | 34 | private: 35 | 36 | D3D11DeviceContext* m_container; 37 | 38 | // Stack depth for non-finalized BeginEvent calls 39 | int32_t m_eventDepth; 40 | }; 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/d3d11/d3d11_class_linkage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d11_device_child.h" 4 | 5 | namespace dxvk { 6 | 7 | class D3D11Device; 8 | 9 | // TODO implement properly 10 | class D3D11ClassLinkage : public D3D11DeviceChild { 11 | 12 | public: 13 | 14 | D3D11ClassLinkage( 15 | D3D11Device* pDevice); 16 | 17 | ~D3D11ClassLinkage(); 18 | 19 | HRESULT STDMETHODCALLTYPE QueryInterface( 20 | REFIID riid, 21 | void** ppvObject) final; 22 | 23 | HRESULT STDMETHODCALLTYPE CreateClassInstance( 24 | LPCSTR pClassTypeName, 25 | UINT ConstantBufferOffset, 26 | UINT ConstantVectorOffset, 27 | UINT TextureOffset, 28 | UINT SamplerOffset, 29 | ID3D11ClassInstance **ppInstance); 30 | 31 | HRESULT STDMETHODCALLTYPE GetClassInstance( 32 | LPCSTR pClassInstanceName, 33 | UINT InstanceIndex, 34 | ID3D11ClassInstance **ppInstance); 35 | 36 | }; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/d3d11/d3d11_cmd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d11_include.h" 4 | 5 | namespace dxvk { 6 | 7 | /** 8 | * \brief D3D11 command type 9 | * 10 | * Used to identify the type of command 11 | * data most recently added to a CS chunk. 12 | */ 13 | enum class D3D11CmdType { 14 | DrawIndirect, 15 | DrawIndirectIndexed, 16 | }; 17 | 18 | 19 | /** 20 | * \brief Command data header 21 | * 22 | * Stores the command type. All command 23 | * data structs must inherit this struct. 24 | */ 25 | struct D3D11CmdData { 26 | D3D11CmdType type; 27 | }; 28 | 29 | 30 | /** 31 | * \brief Indirect draw command data 32 | * 33 | * Stores the offset into the draw buffer for 34 | * the first draw, as well as the number of 35 | * draws to execute. 36 | */ 37 | struct D3D11CmdDrawIndirectData : public D3D11CmdData { 38 | uint32_t offset; 39 | uint32_t count; 40 | uint32_t stride; 41 | }; 42 | 43 | } -------------------------------------------------------------------------------- /src/d3d11/d3d11_cmdlist.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d11_context.h" 4 | 5 | namespace dxvk { 6 | 7 | class D3D11CommandList : public D3D11DeviceChild { 8 | 9 | public: 10 | 11 | D3D11CommandList( 12 | D3D11Device* pDevice, 13 | UINT ContextFlags); 14 | 15 | ~D3D11CommandList(); 16 | 17 | HRESULT STDMETHODCALLTYPE QueryInterface( 18 | REFIID riid, 19 | void** ppvObject) final; 20 | 21 | UINT STDMETHODCALLTYPE GetContextFlags() final; 22 | 23 | void AddChunk( 24 | DxvkCsChunkRef&& Chunk); 25 | 26 | void AddQuery( 27 | D3D11Query* pQuery); 28 | 29 | void EmitToCommandList( 30 | ID3D11CommandList* pCommandList); 31 | 32 | void EmitToCsThread( 33 | DxvkCsThread* CsThread); 34 | 35 | private: 36 | 37 | UINT const m_contextFlags; 38 | 39 | std::vector m_chunks; 40 | std::vector> m_queries; 41 | 42 | std::atomic m_submitted = { false }; 43 | std::atomic m_warned = { false }; 44 | 45 | void MarkSubmitted(); 46 | 47 | }; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/d3d11/d3d11_enums.cpp: -------------------------------------------------------------------------------- 1 | #include "d3d11_enums.h" 2 | 3 | std::ostream& operator << (std::ostream& os, D3D_FEATURE_LEVEL e) { 4 | switch (e) { 5 | ENUM_NAME(D3D_FEATURE_LEVEL_9_1); 6 | ENUM_NAME(D3D_FEATURE_LEVEL_9_2); 7 | ENUM_NAME(D3D_FEATURE_LEVEL_9_3); 8 | ENUM_NAME(D3D_FEATURE_LEVEL_10_0); 9 | ENUM_NAME(D3D_FEATURE_LEVEL_10_1); 10 | ENUM_NAME(D3D_FEATURE_LEVEL_11_0); 11 | ENUM_NAME(D3D_FEATURE_LEVEL_11_1); 12 | ENUM_DEFAULT(e); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/d3d11/d3d11_enums.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "d3d11_include.h" 6 | 7 | std::ostream& operator << (std::ostream& os, D3D_FEATURE_LEVEL e); -------------------------------------------------------------------------------- /src/d3d11/d3d11_gdi.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "d3d11_include.h" 6 | 7 | namespace dxvk { 8 | 9 | class D3D11GDISurface { 10 | 11 | public: 12 | 13 | D3D11GDISurface( 14 | ID3D11Resource* pResource, 15 | UINT Subresource); 16 | 17 | ~D3D11GDISurface(); 18 | 19 | HRESULT Acquire( 20 | BOOL Discard, 21 | HDC* phdc); 22 | 23 | HRESULT Release( 24 | const RECT* pDirtyRect); 25 | 26 | private: 27 | 28 | ID3D11Resource* m_resource; 29 | uint32_t m_subresource; 30 | ID3D11Resource* m_readback; 31 | HDC m_hdc; 32 | HANDLE m_hbitmap; 33 | bool m_acquired; 34 | 35 | std::vector m_data; 36 | 37 | HRESULT CreateReadbackResource(); 38 | 39 | }; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/d3d11/d3d11_input_layout.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d11_device_child.h" 4 | 5 | #include "../d3d10/d3d10_input_layout.h" 6 | 7 | namespace dxvk { 8 | 9 | class D3D11Device; 10 | 11 | class D3D11InputLayout : public D3D11DeviceChild { 12 | 13 | public: 14 | 15 | D3D11InputLayout( 16 | D3D11Device* pDevice, 17 | uint32_t numAttributes, 18 | const DxvkVertexAttribute* pAttributes, 19 | uint32_t numBindings, 20 | const DxvkVertexBinding* pBindings); 21 | 22 | ~D3D11InputLayout(); 23 | 24 | HRESULT STDMETHODCALLTYPE QueryInterface( 25 | REFIID riid, 26 | void** ppvObject) final; 27 | 28 | void BindToContext( 29 | const Rc& ctx); 30 | 31 | bool Compare( 32 | const D3D11InputLayout* pOther) const; 33 | 34 | D3D10InputLayout* GetD3D10Iface() { 35 | return &m_d3d10; 36 | } 37 | 38 | private: 39 | 40 | std::vector m_attributes; 41 | std::vector m_bindings; 42 | 43 | D3D10InputLayout m_d3d10; 44 | 45 | }; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/d3d11/d3d11_sampler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../dxvk/dxvk_device.h" 4 | 5 | #include "../d3d10/d3d10_sampler.h" 6 | 7 | #include "d3d11_device_child.h" 8 | 9 | namespace dxvk { 10 | 11 | class D3D11Device; 12 | 13 | class D3D11SamplerState : public D3D11StateObject { 14 | 15 | public: 16 | 17 | using DescType = D3D11_SAMPLER_DESC; 18 | 19 | D3D11SamplerState( 20 | D3D11Device* device, 21 | const D3D11_SAMPLER_DESC& desc); 22 | ~D3D11SamplerState(); 23 | 24 | HRESULT STDMETHODCALLTYPE QueryInterface( 25 | REFIID riid, 26 | void** ppvObject) final; 27 | 28 | void STDMETHODCALLTYPE GetDesc( 29 | D3D11_SAMPLER_DESC* pDesc) final; 30 | 31 | Rc GetDXVKSampler() const { 32 | return m_sampler; 33 | } 34 | 35 | D3D10SamplerState* GetD3D10Iface() { 36 | return &m_d3d10; 37 | } 38 | 39 | static HRESULT NormalizeDesc( 40 | D3D11_SAMPLER_DESC* pDesc); 41 | 42 | private: 43 | 44 | D3D11_SAMPLER_DESC m_desc; 45 | Rc m_sampler; 46 | D3D10SamplerState m_d3d10; 47 | 48 | std::atomic m_refCount = { 0u }; 49 | 50 | static bool ValidateAddressMode( 51 | D3D11_TEXTURE_ADDRESS_MODE Mode); 52 | 53 | static bool ValidateComparisonFunc( 54 | D3D11_COMPARISON_FUNC Comparison); 55 | 56 | }; 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/d3d11/d3d11_state_object.cpp: -------------------------------------------------------------------------------- 1 | #include "d3d11_state_object.h" 2 | 3 | namespace dxvk { 4 | 5 | D3D11DeviceContextState::D3D11DeviceContextState( 6 | D3D11Device* pDevice) 7 | : D3D11DeviceChild(pDevice) { 8 | 9 | } 10 | 11 | 12 | D3D11DeviceContextState::~D3D11DeviceContextState() { 13 | 14 | } 15 | 16 | 17 | HRESULT STDMETHODCALLTYPE D3D11DeviceContextState::QueryInterface( 18 | REFIID riid, 19 | void** ppvObject) { 20 | if (ppvObject == nullptr) 21 | return E_POINTER; 22 | 23 | *ppvObject = nullptr; 24 | 25 | if (riid == __uuidof(IUnknown) 26 | || riid == __uuidof(ID3D11DeviceChild) 27 | || riid == __uuidof(ID3DDeviceContextState)) { 28 | *ppvObject = ref(this); 29 | return S_OK; 30 | } 31 | 32 | Logger::warn("D3D11DeviceContextState::QueryInterface: Unknown interface query"); 33 | Logger::warn(str::format(riid)); 34 | return E_NOINTERFACE; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/d3d11/d3d11_state_object.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d11_device.h" 4 | #include "d3d11_context_state.h" 5 | #include "d3d11_device_child.h" 6 | 7 | namespace dxvk { 8 | 9 | /** 10 | * \brief Device context state implementation 11 | * 12 | * This is an opaque interface in D3D11, and we only 13 | * implement the state block-like functionality, not 14 | * the methods to disable certain context and device 15 | * interfaces based on the emulated device IID. 16 | */ 17 | class D3D11DeviceContextState : public D3D11DeviceChild { 18 | 19 | public: 20 | 21 | D3D11DeviceContextState( 22 | D3D11Device* pDevice); 23 | 24 | ~D3D11DeviceContextState(); 25 | 26 | HRESULT STDMETHODCALLTYPE QueryInterface( 27 | REFIID riid, 28 | void** ppvObject); 29 | 30 | void SetState(const D3D11ContextState& State) { 31 | m_state = State; 32 | } 33 | 34 | void GetState(D3D11ContextState& State) const { 35 | State = m_state; 36 | } 37 | 38 | private: 39 | 40 | D3D11ContextState m_state; 41 | 42 | }; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/d3d11/d3d11_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../dxvk/dxvk_device.h" 4 | 5 | #include "../dxbc/dxbc_util.h" 6 | 7 | #include "d3d11_include.h" 8 | 9 | namespace dxvk { 10 | 11 | template 12 | UINT CompactSparseList(T* pData, UINT Mask) { 13 | uint32_t count = 0; 14 | 15 | for (uint32_t id : bit::BitMask(Mask)) 16 | pData[count++] = pData[id]; 17 | 18 | return count; 19 | } 20 | 21 | HRESULT DecodeSampleCount( 22 | UINT Count, 23 | VkSampleCountFlagBits* pCount); 24 | 25 | VkSamplerAddressMode DecodeAddressMode( 26 | D3D11_TEXTURE_ADDRESS_MODE mode); 27 | 28 | VkCompareOp DecodeCompareOp( 29 | D3D11_COMPARISON_FUNC Mode); 30 | 31 | VkConservativeRasterizationModeEXT DecodeConservativeRasterizationMode( 32 | D3D11_CONSERVATIVE_RASTERIZATION_MODE Mode); 33 | 34 | VkShaderStageFlagBits GetShaderStage( 35 | DxbcProgramType ProgramType); 36 | 37 | VkFormatFeatureFlags GetBufferFormatFeatures( 38 | UINT BindFlags); 39 | 40 | VkFormatFeatureFlags GetImageFormatFeatures( 41 | UINT BindFlags); 42 | 43 | VkFormat GetPackedDepthStencilFormat( 44 | DXGI_FORMAT Format); 45 | 46 | } -------------------------------------------------------------------------------- /src/d3d11/shaders/d3d11_video_blit_vert.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) out vec2 o_texcoord; 4 | 5 | void main() { 6 | vec2 coord = vec2( 7 | float(gl_VertexIndex & 1) * 2.0f, 8 | float(gl_VertexIndex & 2)); 9 | 10 | o_texcoord = coord; 11 | gl_Position = vec4(-1.0f + 2.0f * coord, 0.0f, 1.0f); 12 | } 13 | -------------------------------------------------------------------------------- /src/d3d11/version.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // DLL version information. 4 | VS_VERSION_INFO VERSIONINFO 5 | FILEVERSION 10,0,17763,1 6 | PRODUCTVERSION 10,0,17763,1 7 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 8 | FILEFLAGS 0 9 | FILEOS VOS_NT_WINDOWS32 10 | FILETYPE VFT_DLL 11 | FILESUBTYPE VFT2_UNKNOWN 12 | BEGIN 13 | BLOCK "StringFileInfo" 14 | BEGIN 15 | BLOCK "080904b0" 16 | BEGIN 17 | VALUE "CompanyName", "DXVK" 18 | VALUE "FileDescription", "Direct3D 11 Runtime" 19 | VALUE "FileVersion", "10.0.17763.1 (WinBuild.160101.0800)" 20 | VALUE "InternalName", "D3D11.dll" 21 | VALUE "LegalCopyright", "zlib/libpng license" 22 | VALUE "OriginalFilename", "D3D11.dll" 23 | VALUE "ProductName", "DXVK" 24 | VALUE "ProductVersion", "10.0.17763.1" 25 | END 26 | END 27 | BLOCK "VarFileInfo" 28 | BEGIN 29 | VALUE "Translation", 0x0809, 1200 30 | END 31 | END 32 | 33 | -------------------------------------------------------------------------------- /src/d3d9/d3d9.def: -------------------------------------------------------------------------------- 1 | LIBRARY D3D9.DLL 2 | EXPORTS 3 | Direct3DShaderValidatorCreate9 @24 4 | 5 | PSGPError @25 6 | PSGPSampleTexture @26 7 | 8 | D3DPERF_BeginEvent @27 9 | D3DPERF_EndEvent @28 10 | D3DPERF_GetStatus @29 11 | D3DPERF_QueryRepeatFrame @30 12 | D3DPERF_SetMarker @31 13 | D3DPERF_SetOptions @32 14 | D3DPERF_SetRegion @33 15 | 16 | DebugSetLevel @34 17 | DebugSetMute @35 18 | 19 | Direct3D9EnableMaximizedWindowedModeShim @36 20 | 21 | Direct3DCreate9 @37 22 | Direct3DCreate9Ex @38 23 | -------------------------------------------------------------------------------- /src/d3d9/d3d9_caps.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d9_include.h" 4 | 5 | namespace dxvk::caps { 6 | 7 | constexpr uint32_t MaxClipPlanes = 6; 8 | constexpr uint32_t MaxSamplers = 16; 9 | constexpr uint32_t MaxStreams = 16; 10 | constexpr uint32_t MaxSimultaneousTextures = 8; 11 | constexpr uint32_t MaxTextureBlendStages = MaxSimultaneousTextures; 12 | constexpr uint32_t MaxSimultaneousRenderTargets = D3D_MAX_SIMULTANEOUS_RENDERTARGETS; 13 | 14 | constexpr uint32_t MaxFloatConstantsVS = 256; 15 | constexpr uint32_t MaxFloatConstantsPS = 224; 16 | constexpr uint32_t MaxOtherConstants = 16; 17 | constexpr uint32_t MaxFloatConstantsSoftware = 8192; 18 | constexpr uint32_t MaxOtherConstantsSoftware = 2048; 19 | 20 | constexpr uint32_t InputRegisterCount = 16; 21 | 22 | constexpr uint32_t MaxTextureDimension = 16384; 23 | constexpr uint32_t MaxMipLevels = 15; 24 | constexpr uint32_t MaxSubresources = 15 * 6; 25 | 26 | constexpr uint32_t MaxTransforms = 10 + 256; 27 | 28 | constexpr uint32_t TextureStageCount = MaxSimultaneousTextures; 29 | 30 | constexpr uint32_t MaxEnabledLights = 8; 31 | 32 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_constant_layout.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "d3d9_caps.h" 6 | 7 | namespace dxvk { 8 | 9 | struct D3D9ConstantLayout { 10 | uint32_t floatCount; 11 | uint32_t intCount; 12 | uint32_t boolCount; 13 | uint32_t bitmaskCount; 14 | 15 | uint32_t floatSize() const { return floatCount * 4 * sizeof(float); } 16 | uint32_t intSize() const { return intCount * 4 * sizeof(int); } 17 | uint32_t bitmaskSize() const { 18 | // Account for SWVP (non SWVP uses a spec constant) 19 | return bitmaskCount != 1 20 | ? bitmaskCount * 1 * sizeof(uint32_t) 21 | : 0; 22 | } 23 | 24 | uint32_t floatOffset() const { return 0; } 25 | uint32_t intOffset() const { return floatOffset() + floatSize(); } 26 | uint32_t bitmaskOffset() const { return intOffset() + intSize(); } 27 | 28 | uint32_t totalSize() const { return floatSize() + intSize() + bitmaskSize(); } 29 | }; 30 | 31 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_constant_set.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d9_caps.h" 4 | 5 | #include "../dxvk/dxvk_buffer.h" 6 | 7 | #include "../dxso/dxso_isgn.h" 8 | 9 | #include "../util/util_math.h" 10 | #include "../util/util_vector.h" 11 | 12 | #include 13 | 14 | namespace dxvk { 15 | 16 | enum class D3D9ConstantType { 17 | Float, 18 | Int, 19 | Bool 20 | }; 21 | 22 | // We make an assumption later based on the packing of this struct for copying. 23 | struct D3D9ShaderConstantsVSSoftware { 24 | Vector4 fConsts[caps::MaxFloatConstantsSoftware]; 25 | Vector4i iConsts[caps::MaxOtherConstantsSoftware]; 26 | uint32_t bConsts[caps::MaxOtherConstantsSoftware / 32]; 27 | }; 28 | 29 | struct D3D9ShaderConstantsVSHardware { 30 | Vector4 fConsts[caps::MaxFloatConstantsVS]; 31 | Vector4i iConsts[caps::MaxOtherConstants]; 32 | uint32_t bConsts[1]; 33 | }; 34 | 35 | struct D3D9ShaderConstantsPS { 36 | Vector4 fConsts[caps::MaxFloatConstantsPS]; 37 | Vector4i iConsts[caps::MaxOtherConstants]; 38 | uint32_t bConsts[1]; 39 | }; 40 | 41 | struct D3D9ConstantSets { 42 | Rc buffer; 43 | DxsoShaderMetaInfo meta = {}; 44 | bool dirty = true; 45 | }; 46 | 47 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_cursor.cpp: -------------------------------------------------------------------------------- 1 | #include "d3d9_cursor.h" 2 | #include "d3d9_util.h" 3 | 4 | #include 5 | 6 | namespace dxvk { 7 | 8 | void D3D9Cursor::UpdateCursor(int X, int Y) { 9 | POINT currentPos = { }; 10 | if (::GetCursorPos(¤tPos) && currentPos == POINT{ X, Y }) 11 | return; 12 | 13 | ::SetCursorPos(X, Y); 14 | } 15 | 16 | 17 | BOOL D3D9Cursor::ShowCursor(BOOL bShow) { 18 | ::SetCursor(bShow ? m_hCursor : nullptr); 19 | return std::exchange(m_visible, bShow); 20 | } 21 | 22 | 23 | HRESULT D3D9Cursor::SetHardwareCursor(UINT XHotSpot, UINT YHotSpot, const CursorBitmap& bitmap) { 24 | DWORD mask[32]; 25 | std::memset(mask, ~0, sizeof(mask)); 26 | 27 | ICONINFO info; 28 | info.fIcon = FALSE; 29 | info.xHotspot = XHotSpot; 30 | info.yHotspot = YHotSpot; 31 | info.hbmMask = ::CreateBitmap(HardwareCursorWidth, HardwareCursorHeight, 1, 1, mask); 32 | info.hbmColor = ::CreateBitmap(HardwareCursorWidth, HardwareCursorHeight, 1, 32, &bitmap[0]); 33 | 34 | if (m_hCursor != nullptr) 35 | ::DestroyCursor(m_hCursor); 36 | 37 | m_hCursor = ::CreateIconIndirect(&info); 38 | 39 | ::DeleteObject(info.hbmMask); 40 | ::DeleteObject(info.hbmColor); 41 | 42 | ShowCursor(m_visible); 43 | 44 | return D3D_OK; 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_cursor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d9_include.h" 4 | 5 | namespace dxvk { 6 | 7 | constexpr uint32_t HardwareCursorWidth = 32u; 8 | constexpr uint32_t HardwareCursorHeight = 32u; 9 | constexpr uint32_t HardwareCursorFormatSize = 4u; 10 | constexpr uint32_t HardwareCursorPitch = HardwareCursorWidth * HardwareCursorFormatSize; 11 | 12 | // Format Size of 4 bytes (ARGB) 13 | using CursorBitmap = uint8_t[HardwareCursorHeight * HardwareCursorPitch]; 14 | 15 | class D3D9Cursor { 16 | 17 | public: 18 | 19 | void UpdateCursor(int X, int Y); 20 | 21 | BOOL ShowCursor(BOOL bShow); 22 | 23 | HRESULT SetHardwareCursor(UINT XHotSpot, UINT YHotSpot, const CursorBitmap& bitmap); 24 | 25 | private: 26 | 27 | BOOL m_visible = FALSE; 28 | 29 | HCURSOR m_hCursor = nullptr; 30 | 31 | }; 32 | 33 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_device_child.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d9_include.h" 4 | 5 | namespace dxvk { 6 | 7 | class D3D9DeviceEx; 8 | 9 | template 10 | class D3D9DeviceChild : public ComObjectClamp { 11 | 12 | public: 13 | 14 | D3D9DeviceChild(D3D9DeviceEx* pDevice) 15 | : m_parent( pDevice ) { } 16 | 17 | ULONG STDMETHODCALLTYPE AddRef() { 18 | uint32_t refCount = this->m_refCount++; 19 | if (unlikely(!refCount)) { 20 | this->AddRefPrivate(); 21 | GetDevice()->AddRef(); 22 | } 23 | 24 | return refCount + 1; 25 | } 26 | 27 | ULONG STDMETHODCALLTYPE Release() { 28 | uint32_t refCount = --this->m_refCount; 29 | if (unlikely(!refCount)) { 30 | auto* pDevice = GetDevice(); 31 | this->ReleasePrivate(); 32 | pDevice->Release(); 33 | } 34 | return refCount; 35 | } 36 | 37 | HRESULT STDMETHODCALLTYPE GetDevice(IDirect3DDevice9** ppDevice) { 38 | InitReturnPtr(ppDevice); 39 | 40 | if (ppDevice == nullptr) 41 | return D3DERR_INVALIDCALL; 42 | 43 | *ppDevice = ref(GetDevice()); 44 | return D3D_OK; 45 | } 46 | 47 | IDirect3DDevice9Ex* GetDevice() { 48 | return reinterpret_cast(m_parent); 49 | } 50 | 51 | D3D9DeviceEx* GetParent() { 52 | return m_parent; 53 | } 54 | 55 | protected: 56 | 57 | D3D9DeviceEx* m_parent; 58 | 59 | }; 60 | 61 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_format_helpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d9_include.h" 4 | #include "d3d9_format.h" 5 | #include "../dxvk/dxvk_device.h" 6 | #include "../dxvk/dxvk_context.h" 7 | 8 | namespace dxvk { 9 | 10 | class D3D9FormatHelper { 11 | 12 | public: 13 | 14 | D3D9FormatHelper(const Rc& device); 15 | 16 | void Flush(); 17 | 18 | void ConvertFormat( 19 | D3D9_CONVERSION_FORMAT_INFO conversionFormat, 20 | const Rc& dstImage, 21 | VkImageSubresourceLayers dstSubresource, 22 | const DxvkBufferSlice& srcSlice); 23 | 24 | private: 25 | 26 | void ConvertGenericFormat( 27 | D3D9_CONVERSION_FORMAT_INFO videoFormat, 28 | const Rc& dstImage, 29 | VkImageSubresourceLayers dstSubresource, 30 | const DxvkBufferSlice& srcSlice, 31 | VkFormat bufferFormat, 32 | uint32_t specConstantValue, 33 | VkExtent2D macroPixelRun); 34 | 35 | enum BindingIds : uint32_t { 36 | Image = 0, 37 | Buffer = 1, 38 | }; 39 | 40 | void InitShaders(); 41 | 42 | Rc InitShader(SpirvCodeBuffer code); 43 | 44 | void FlushInternal(); 45 | 46 | Rc m_device; 47 | Rc m_context; 48 | 49 | size_t m_transferCommands = 0; 50 | 51 | std::array, D3D9ConversionFormat_Count> m_shaders; 52 | 53 | }; 54 | 55 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_hud.cpp: -------------------------------------------------------------------------------- 1 | #include "d3d9_hud.h" 2 | 3 | namespace dxvk::hud { 4 | 5 | HudSamplerCount::HudSamplerCount(D3D9DeviceEx* device) 6 | : m_device (device) 7 | , m_samplerCount ("0"){ 8 | 9 | } 10 | 11 | 12 | void HudSamplerCount::update(dxvk::high_resolution_clock::time_point time) { 13 | m_samplerCount = str::format(m_device->GetSamplerCount()); 14 | } 15 | 16 | 17 | HudPos HudSamplerCount::render( 18 | HudRenderer& renderer, 19 | HudPos position) { 20 | position.y += 16.0f; 21 | 22 | renderer.drawText(16.0f, 23 | { position.x, position.y }, 24 | { 0.0f, 1.0f, 0.75f, 1.0f }, 25 | "Samplers:"); 26 | 27 | renderer.drawText(16.0f, 28 | { position.x + 120.0f, position.y }, 29 | { 1.0f, 1.0f, 1.0f, 1.0f }, 30 | m_samplerCount); 31 | 32 | position.y += 8.0f; 33 | return position; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_hud.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d9_device.h" 4 | #include "../dxvk/hud/dxvk_hud_item.h" 5 | 6 | namespace dxvk::hud { 7 | 8 | /** 9 | * \brief HUD item to display DXVK version 10 | */ 11 | class HudSamplerCount : public HudItem { 12 | 13 | public: 14 | 15 | HudSamplerCount(D3D9DeviceEx* device); 16 | 17 | void update(dxvk::high_resolution_clock::time_point time); 18 | 19 | HudPos render( 20 | HudRenderer& renderer, 21 | HudPos position); 22 | 23 | private: 24 | 25 | D3D9DeviceEx* m_device; 26 | 27 | std::string m_samplerCount; 28 | 29 | }; 30 | 31 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_initializer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d9_common_buffer.h" 4 | #include "d3d9_common_texture.h" 5 | 6 | namespace dxvk { 7 | 8 | /** 9 | * \brief Resource initialization context 10 | * 11 | * Manages a context which is used for resource 12 | * initialization. This includes 13 | * zero-initialization for buffers and images. 14 | */ 15 | class D3D9Initializer { 16 | constexpr static size_t MaxTransferMemory = 32 * 1024 * 1024; 17 | constexpr static size_t MaxTransferCommands = 512; 18 | public: 19 | 20 | D3D9Initializer( 21 | const Rc& Device); 22 | 23 | ~D3D9Initializer(); 24 | 25 | void Flush(); 26 | 27 | void InitBuffer( 28 | D3D9CommonBuffer* pBuffer); 29 | 30 | void InitTexture( 31 | D3D9CommonTexture* pTexture, 32 | void* pInitialData = nullptr); 33 | 34 | private: 35 | 36 | dxvk::mutex m_mutex; 37 | 38 | Rc m_device; 39 | Rc m_context; 40 | 41 | size_t m_transferCommands = 0; 42 | size_t m_transferMemory = 0; 43 | 44 | void InitDeviceLocalBuffer( 45 | DxvkBufferSlice Slice); 46 | 47 | void InitHostVisibleBuffer( 48 | DxvkBufferSlice Slice); 49 | 50 | void InitDeviceLocalTexture( 51 | D3D9CommonTexture* pTexture); 52 | 53 | void InitHostVisibleTexture( 54 | D3D9CommonTexture* pTexture, 55 | void* pInitialData); 56 | 57 | void FlushImplicit(); 58 | void FlushInternal(); 59 | 60 | }; 61 | 62 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_monitor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d9_include.h" 4 | 5 | #include "d3d9_format.h" 6 | 7 | namespace dxvk { 8 | 9 | /** 10 | * \brief Queries bits per pixel for a format 11 | * 12 | * The format must be a valid swap chain format. 13 | * \param [in] Format The D3D9 format to query 14 | * \returns Bits per pixel for this format 15 | */ 16 | uint32_t GetMonitorFormatBpp( 17 | D3D9Format Format); 18 | 19 | /** 20 | * \brief Returns if a format is supported for a backbuffer/swapchain. 21 | * 22 | * \param [in] Format The D3D9 format to query 23 | * \returns If it is supported as a swapchain/backbuffer format. 24 | */ 25 | bool IsSupportedAdapterFormat( 26 | D3D9Format Format); 27 | 28 | bool IsSupportedBackBufferFormat( 29 | D3D9Format AdapterFormat, 30 | D3D9Format BackBufferFormat, 31 | BOOL Windowed); 32 | 33 | bool IsSupportedBackBufferFormat( 34 | D3D9Format BackBufferFormat); 35 | } 36 | -------------------------------------------------------------------------------- /src/d3d9/d3d9_multithread.cpp: -------------------------------------------------------------------------------- 1 | #include "d3d9_device.h" 2 | 3 | namespace dxvk { 4 | 5 | D3D9Multithread::D3D9Multithread( 6 | BOOL Protected) 7 | : m_protected( Protected ) { } 8 | 9 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_multithread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d9_include.h" 4 | 5 | namespace dxvk { 6 | 7 | /** 8 | * \brief Device lock 9 | * 10 | * Lightweight RAII wrapper that implements 11 | * a subset of the functionality provided by 12 | * \c std::unique_lock, with the goal of being 13 | * cheaper to construct and destroy. 14 | */ 15 | class D3D9DeviceLock { 16 | 17 | public: 18 | 19 | D3D9DeviceLock() 20 | : m_mutex(nullptr) { } 21 | 22 | D3D9DeviceLock(sync::RecursiveSpinlock& mutex) 23 | : m_mutex(&mutex) { 24 | mutex.lock(); 25 | } 26 | 27 | D3D9DeviceLock(D3D9DeviceLock&& other) 28 | : m_mutex(other.m_mutex) { 29 | other.m_mutex = nullptr; 30 | } 31 | 32 | D3D9DeviceLock& operator = (D3D9DeviceLock&& other) { 33 | if (m_mutex) 34 | m_mutex->unlock(); 35 | 36 | m_mutex = other.m_mutex; 37 | other.m_mutex = nullptr; 38 | return *this; 39 | } 40 | 41 | ~D3D9DeviceLock() { 42 | if (m_mutex != nullptr) 43 | m_mutex->unlock(); 44 | } 45 | 46 | private: 47 | 48 | sync::RecursiveSpinlock* m_mutex; 49 | 50 | }; 51 | 52 | 53 | /** 54 | * \brief D3D9 context lock 55 | */ 56 | class D3D9Multithread { 57 | 58 | public: 59 | 60 | D3D9Multithread( 61 | BOOL Protected); 62 | 63 | D3D9DeviceLock AcquireLock() { 64 | return m_protected 65 | ? D3D9DeviceLock(m_mutex) 66 | : D3D9DeviceLock(); 67 | } 68 | 69 | private: 70 | 71 | BOOL m_protected; 72 | 73 | sync::RecursiveSpinlock m_mutex; 74 | 75 | }; 76 | 77 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_names.h: -------------------------------------------------------------------------------- 1 | #include "d3d9_include.h" 2 | 3 | namespace dxvk { 4 | 5 | std::ostream& operator << (std::ostream& os, D3DRENDERSTATETYPE e); 6 | 7 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_sampler.cpp: -------------------------------------------------------------------------------- 1 | #include "d3d9_sampler.h" 2 | 3 | namespace dxvk { 4 | 5 | size_t D3D9SamplerKeyHash::operator () (const D3D9SamplerKey& key) const { 6 | DxvkHashState state; 7 | 8 | std::hash dhash; 9 | std::hash tahash; 10 | std::hash tfhash; 11 | std::hash fhash; 12 | std::hash bhash; 13 | 14 | state.add(tahash(key.AddressU)); 15 | state.add(tahash(key.AddressV)); 16 | state.add(tahash(key.AddressW)); 17 | state.add(tfhash(key.MagFilter)); 18 | state.add(tfhash(key.MinFilter)); 19 | state.add(tfhash(key.MipFilter)); 20 | state.add(dhash (key.MaxAnisotropy)); 21 | state.add(fhash (key.MipmapLodBias)); 22 | state.add(dhash (key.MaxMipLevel)); 23 | state.add(dhash (key.BorderColor)); 24 | state.add(bhash (key.Depth)); 25 | 26 | return state; 27 | } 28 | 29 | 30 | bool D3D9SamplerKeyEq::operator () (const D3D9SamplerKey& a, const D3D9SamplerKey& b) const { 31 | return a.AddressU == b.AddressU 32 | && a.AddressV == b.AddressV 33 | && a.AddressW == b.AddressW 34 | && a.MagFilter == b.MagFilter 35 | && a.MinFilter == b.MinFilter 36 | && a.MipFilter == b.MipFilter 37 | && a.MaxAnisotropy == b.MaxAnisotropy 38 | && a.MipmapLodBias == b.MipmapLodBias 39 | && a.MaxMipLevel == b.MaxMipLevel 40 | && a.BorderColor == b.BorderColor 41 | && a.Depth == b.Depth; 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_shader_permutations.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d9_include.h" 4 | 5 | namespace dxvk { 6 | 7 | class DxvkShader; 8 | 9 | namespace D3D9ShaderPermutations { 10 | enum D3D9ShaderPermutation { 11 | None, 12 | FlatShade, 13 | Count 14 | }; 15 | } 16 | using D3D9ShaderPermutation = D3D9ShaderPermutations::D3D9ShaderPermutation; 17 | 18 | using DxsoPermutations = std::array, D3D9ShaderPermutations::Count>; 19 | 20 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_shader_validator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d9_include.h" 4 | 5 | namespace dxvk { 6 | 7 | class IDirect3DShaderValidator9 : public IUnknown { 8 | 9 | public: 10 | 11 | virtual HRESULT STDMETHODCALLTYPE Begin( 12 | void* pCallback, 13 | void* pUserParam, 14 | DWORD Unknown) = 0; 15 | 16 | virtual HRESULT STDMETHODCALLTYPE Instruction( 17 | const char* pUnknown1, 18 | UINT Unknown2, 19 | const DWORD* pInstruction, 20 | DWORD InstructionLength) = 0; 21 | 22 | virtual HRESULT STDMETHODCALLTYPE End() = 0; 23 | 24 | }; 25 | 26 | class D3D9ShaderValidator final : public ComObjectClamp { 27 | 28 | public: 29 | 30 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) { 31 | if (ppvObject == nullptr) 32 | return E_POINTER; 33 | 34 | *ppvObject = ref(this); 35 | return S_OK; 36 | } 37 | 38 | 39 | HRESULT STDMETHODCALLTYPE Begin( 40 | void* pCallback, 41 | void* pUserParam, 42 | DWORD Unknown) { 43 | Logger::debug("D3D9ShaderValidator::Begin: Stub"); 44 | 45 | return D3D_OK; 46 | } 47 | 48 | 49 | HRESULT STDMETHODCALLTYPE Instruction( 50 | const char* pUnknown1, 51 | UINT Unknown2, 52 | const DWORD* pInstruction, 53 | DWORD InstructionLength) { 54 | Logger::debug("D3D9ShaderValidator::Instruction: Stub"); 55 | 56 | return D3D_OK; 57 | } 58 | 59 | 60 | HRESULT STDMETHODCALLTYPE End() { 61 | Logger::debug("D3D9ShaderValidator::End: Stub"); 62 | 63 | return D3D_OK; 64 | } 65 | 66 | }; 67 | 68 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_spec_constants.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace dxvk { 6 | 7 | enum D3D9SpecConstantId : uint32_t { 8 | AlphaCompareOp = 0, 9 | SamplerType = 1, 10 | FogEnabled = 2, 11 | VertexFogMode = 3, 12 | PixelFogMode = 4, 13 | 14 | PointMode = 5, 15 | ProjectionType = 6, 16 | 17 | VertexShaderBools = 7, 18 | PixelShaderBools = 8, 19 | Fetch4 = 9, 20 | 21 | SamplerDepthMode = 10, 22 | }; 23 | 24 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_state.cpp: -------------------------------------------------------------------------------- 1 | #include "d3d9_state.h" 2 | 3 | #include "d3d9_texture.h" 4 | 5 | namespace dxvk { 6 | 7 | D3D9CapturableState::D3D9CapturableState() { 8 | for (uint32_t i = 0; i < textures.size(); i++) 9 | textures[i] = nullptr; 10 | 11 | for (uint32_t i = 0; i < clipPlanes.size(); i++) 12 | clipPlanes[i] = D3D9ClipPlane(); 13 | 14 | for (uint32_t i = 0; i < streamFreq.size(); i++) 15 | streamFreq[i] = 1; 16 | 17 | for (uint32_t i = 0; i < enabledLightIndices.size(); i++) 18 | enabledLightIndices[i] = UINT32_MAX; 19 | } 20 | 21 | D3D9CapturableState::~D3D9CapturableState() { 22 | for (uint32_t i = 0; i < textures.size(); i++) 23 | TextureChangePrivate(textures[i], nullptr); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/d3d9/d3d9_swvp_emu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "d3d9_include.h" 6 | 7 | #include "../dxvk/dxvk_shader.h" 8 | 9 | namespace dxvk { 10 | 11 | class D3D9VertexDecl; 12 | class D3D9DeviceEx; 13 | 14 | struct D3D9VertexDeclHash { 15 | size_t operator () (const D3D9VertexElements& key) const; 16 | }; 17 | 18 | struct D3D9VertexDeclEq { 19 | bool operator () (const D3D9VertexElements& a, const D3D9VertexElements& b) const; 20 | }; 21 | 22 | class D3D9SWVPEmulator { 23 | 24 | public: 25 | 26 | Rc GetShaderModule(D3D9DeviceEx* pDevice, const D3D9VertexDecl* pDecl); 27 | 28 | private: 29 | 30 | dxvk::mutex m_mutex; 31 | 32 | std::unordered_map< 33 | D3D9VertexElements, Rc, 34 | D3D9VertexDeclHash, D3D9VertexDeclEq> m_modules; 35 | 36 | }; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/d3d9/d3d9_volume.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "d3d9_subresource.h" 4 | 5 | #include "d3d9_common_texture.h" 6 | 7 | namespace dxvk { 8 | 9 | using D3D9VolumeBase = D3D9Subresource; 10 | class D3D9Volume final : public D3D9VolumeBase { 11 | 12 | public: 13 | 14 | D3D9Volume( 15 | D3D9DeviceEx* pDevice, 16 | const D3D9_COMMON_TEXTURE_DESC* pDesc); 17 | 18 | D3D9Volume( 19 | D3D9DeviceEx* pDevice, 20 | D3D9CommonTexture* pTexture, 21 | UINT Face, 22 | UINT MipLevel, 23 | IDirect3DBaseTexture9* pContainer); 24 | 25 | void AddRefPrivate(); 26 | 27 | void ReleasePrivate(); 28 | 29 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); 30 | 31 | HRESULT STDMETHODCALLTYPE GetDesc(D3DVOLUME_DESC *pDesc) final; 32 | 33 | HRESULT STDMETHODCALLTYPE LockBox(D3DLOCKED_BOX* pLockedBox, CONST D3DBOX* pBox, DWORD Flags) final; 34 | 35 | HRESULT STDMETHODCALLTYPE UnlockBox() final; 36 | 37 | }; 38 | } -------------------------------------------------------------------------------- /src/d3d9/meson.build: -------------------------------------------------------------------------------- 1 | d3d9_res = wrc_generator.process('version.rc') 2 | 3 | d3d9_shaders = files([ 4 | 'shaders/d3d9_convert_yuy2_uyvy.comp', 5 | 'shaders/d3d9_convert_l6v5u5.comp', 6 | 'shaders/d3d9_convert_x8l8v8u8.comp', 7 | 'shaders/d3d9_convert_a2w10v10u10.comp', 8 | 'shaders/d3d9_convert_nv12.comp', 9 | 'shaders/d3d9_convert_yv12.comp' 10 | ]) 11 | 12 | d3d9_src = [ 13 | 'd3d9_main.cpp', 14 | 'd3d9_interface.cpp', 15 | 'd3d9_adapter.cpp', 16 | 'd3d9_monitor.cpp', 17 | 'd3d9_device.cpp', 18 | 'd3d9_state.cpp', 19 | 'd3d9_cursor.cpp', 20 | 'd3d9_swapchain.cpp', 21 | 'd3d9_format.cpp', 22 | 'd3d9_common_texture.cpp', 23 | 'd3d9_texture.cpp', 24 | 'd3d9_surface.cpp', 25 | 'd3d9_volume.cpp', 26 | 'd3d9_common_buffer.cpp', 27 | 'd3d9_buffer.cpp', 28 | 'd3d9_shader.cpp', 29 | 'd3d9_vertex_declaration.cpp', 30 | 'd3d9_query.cpp', 31 | 'd3d9_multithread.cpp', 32 | 'd3d9_options.cpp', 33 | 'd3d9_stateblock.cpp', 34 | 'd3d9_sampler.cpp', 35 | 'd3d9_util.cpp', 36 | 'd3d9_initializer.cpp', 37 | 'd3d9_fixed_function.cpp', 38 | 'd3d9_names.cpp', 39 | 'd3d9_swvp_emu.cpp', 40 | 'd3d9_format_helpers.cpp', 41 | 'd3d9_hud.cpp' 42 | ] 43 | 44 | d3d9_dll = shared_library('d3d9'+dll_ext, d3d9_src, glsl_generator.process(d3d9_shaders), d3d9_res, 45 | name_prefix : '', 46 | dependencies : [ dxso_dep, dxvk_dep ], 47 | include_directories : dxvk_include_path, 48 | install : true, 49 | vs_module_defs : 'd3d9'+def_spec_ext, 50 | override_options : ['cpp_std='+dxvk_cpp_std]) 51 | 52 | d3d9_dep = declare_dependency( 53 | link_with : [ d3d9_dll ], 54 | include_directories : [ dxvk_include_path ]) 55 | -------------------------------------------------------------------------------- /src/d3d9/shaders/d3d9_convert_a2w10v10u10.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_GOOGLE_include_directive : enable 3 | 4 | #include "d3d9_convert_common.h" 5 | 6 | layout( 7 | local_size_x = 8, 8 | local_size_y = 8, 9 | local_size_z = 1) in; 10 | 11 | layout(binding = 0) 12 | writeonly uniform image2D dst; 13 | 14 | layout(binding = 1) uniform usamplerBuffer src; 15 | 16 | layout(push_constant) 17 | uniform u_info_t { 18 | uvec2 extent; 19 | } u_info; 20 | 21 | void main() { 22 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 23 | 24 | if (all(lessThan(thread_id.xy, u_info.extent))) { 25 | uint offset = thread_id.x 26 | + thread_id.y * u_info.extent.x; 27 | 28 | uint value = texelFetch(src, int(offset)).r; 29 | 30 | // Sign-extend magic! 31 | int u10 = bitfieldExtract(int (value), 0, 10); 32 | int v10 = bitfieldExtract(int (value), 10, 10); 33 | int w10 = bitfieldExtract(int (value), 20, 10); 34 | uint a2 = bitfieldExtract(uint(value), 30, 2); 35 | 36 | vec4 color = vec4( 37 | snormalize(u10, 10), 38 | snormalize(v10, 10), 39 | snormalize(w10, 10), 40 | unormalize(a2, 2)); 41 | 42 | imageStore(dst, thread_id.xy, color); 43 | } 44 | } -------------------------------------------------------------------------------- /src/d3d9/shaders/d3d9_convert_common.h: -------------------------------------------------------------------------------- 1 | float unormalize(uint value, int bits) { 2 | const int range = (1 << bits) - 1; 3 | 4 | return float(value) / float(range); 5 | } 6 | 7 | float snormalize(int value, int bits) { 8 | const int range = (1 << (bits - 1)) - 1; 9 | 10 | // Min because, -32 and -31 map to -1.0f, and we 11 | // divide by 31. 12 | return max(float(value) / float(range), -1.0); 13 | } 14 | 15 | float unpackUnorm(uint p) { 16 | return float(p) / 255.0; 17 | } 18 | 19 | vec2 unpackUnorm2x8(uint p) { 20 | uvec2 value = uvec2(p & 0xFF, p >> 8); 21 | return vec2(unpackUnorm(value.x), unpackUnorm(value.y)); 22 | } 23 | 24 | mat3x4 g_yuv_to_rgb = { 25 | { 298 / 256, 0, 409 / 256, 0.5 }, 26 | { 298 / 256, -100 / 256, -208 / 256, 0.5 }, 27 | { 298 / 256, 516 / 256, 0, 0.5 } 28 | }; 29 | 30 | vec4 convertYUV(vec3 yuv) { 31 | vec3 value = vec4(yuv, 1 / 255.0) * g_yuv_to_rgb; 32 | 33 | return vec4(clamp(value, 0, 1), 1); 34 | } 35 | 36 | mat3x3 g_bt709_to_rgb = { 37 | { 1.164, 0, 1.793 }, 38 | { 1.164, -0.213, -0.533 }, 39 | { 1.164, 2.112, 0 } 40 | }; 41 | 42 | vec4 convertBT_709(vec3 cde) { 43 | return vec4(clamp(cde * g_bt709_to_rgb, 0, 1), 1); 44 | } 45 | -------------------------------------------------------------------------------- /src/d3d9/shaders/d3d9_convert_l6v5u5.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_GOOGLE_include_directive : enable 3 | 4 | #include "d3d9_convert_common.h" 5 | 6 | layout( 7 | local_size_x = 8, 8 | local_size_y = 8, 9 | local_size_z = 1) in; 10 | 11 | layout(binding = 0) 12 | writeonly uniform image2D dst; 13 | 14 | layout(binding = 1) uniform usamplerBuffer src; 15 | 16 | layout(push_constant) 17 | uniform u_info_t { 18 | uvec2 extent; 19 | } u_info; 20 | 21 | void main() { 22 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 23 | 24 | if (all(lessThan(thread_id.xy, u_info.extent))) { 25 | uint offset = thread_id.x 26 | + thread_id.y * u_info.extent.x; 27 | 28 | uint value = texelFetch(src, int(offset)).r; 29 | 30 | // Sign-extend magic! 31 | int u5 = bitfieldExtract(int (value), 0, 5); 32 | int v5 = bitfieldExtract(int (value), 5, 5); 33 | uint l6 = bitfieldExtract(uint(value), 10, 6); 34 | 35 | vec4 color = vec4( 36 | snormalize(u5, 5), 37 | snormalize(v5, 5), 38 | unormalize(l6, 6), 39 | 1.0f); 40 | 41 | imageStore(dst, thread_id.xy, color); 42 | } 43 | } -------------------------------------------------------------------------------- /src/d3d9/shaders/d3d9_convert_x8l8v8u8.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_GOOGLE_include_directive : enable 3 | 4 | #include "d3d9_convert_common.h" 5 | 6 | layout( 7 | local_size_x = 8, 8 | local_size_y = 8, 9 | local_size_z = 1) in; 10 | 11 | layout(binding = 0) 12 | writeonly uniform image2D dst; 13 | 14 | layout(binding = 1) uniform usamplerBuffer src; 15 | 16 | layout(push_constant) 17 | uniform u_info_t { 18 | uvec2 extent; 19 | } u_info; 20 | 21 | void main() { 22 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 23 | 24 | if (all(lessThan(thread_id.xy, u_info.extent))) { 25 | uint offset = thread_id.x 26 | + thread_id.y * u_info.extent.x; 27 | 28 | uint value = texelFetch(src, int(offset)).r; 29 | 30 | // Sign-extend magic! 31 | int u8 = bitfieldExtract(int (value), 0, 8); 32 | int v8 = bitfieldExtract(int (value), 8, 8); 33 | uint l8 = bitfieldExtract(uint(value), 16, 8); 34 | 35 | vec4 color = vec4( 36 | snormalize(u8, 8), 37 | snormalize(v8, 8), 38 | unormalize(l8, 8), 39 | 1.0f); 40 | 41 | imageStore(dst, thread_id.xy, color); 42 | } 43 | } -------------------------------------------------------------------------------- /src/d3d9/shaders/d3d9_convert_yuy2_uyvy.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_GOOGLE_include_directive : enable 3 | 4 | #include "d3d9_convert_common.h" 5 | 6 | layout(constant_id = 1225) const bool s_is_uyvy = false; 7 | 8 | layout( 9 | local_size_x = 8, 10 | local_size_y = 8, 11 | local_size_z = 1) in; 12 | 13 | layout(binding = 0) 14 | writeonly uniform image2D dst; 15 | 16 | layout(binding = 1) uniform usamplerBuffer src; 17 | 18 | layout(push_constant) 19 | uniform u_info_t { 20 | uvec2 extent; 21 | } u_info; 22 | 23 | void main() { 24 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 25 | 26 | if (all(lessThan(thread_id.xy, u_info.extent))) { 27 | uint offset = thread_id.x 28 | + thread_id.y * u_info.extent.x; 29 | 30 | uint value = texelFetch(src, int(offset)).r; 31 | 32 | vec4 data = unpackUnorm4x8(value); 33 | 34 | // Flip around stuff for UYVY 35 | if (s_is_uyvy) 36 | data = data.yxwz; 37 | 38 | float y0 = data.x - (16 / 255.0); 39 | float u = data.y - (128 / 255.0); 40 | float y1 = data.z - (16 / 255.0); 41 | float v = data.w - (128 / 255.0); 42 | 43 | vec4 color0 = convertYUV(vec3(y0, u, v)); 44 | vec4 color1 = convertYUV(vec3(y1, u, v)); 45 | 46 | // YUY2 has a macropixel of [2, 1] 47 | // so we write 2 pixels in this run. 48 | ivec2 writePos = thread_id.xy * ivec2(2, 1); 49 | 50 | imageStore(dst, ivec2(writePos.x, writePos.y), color0); 51 | imageStore(dst, ivec2(writePos.x + 1, writePos.y), color1); 52 | } 53 | } -------------------------------------------------------------------------------- /src/d3d9/shaders/d3d9_convert_yv12.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | #extension GL_GOOGLE_include_directive : enable 3 | 4 | #include "d3d9_convert_common.h" 5 | 6 | layout( 7 | local_size_x = 8, 8 | local_size_y = 8, 9 | local_size_z = 1) in; 10 | 11 | layout(binding = 0) 12 | writeonly uniform image2D dst; 13 | 14 | layout(binding = 1) uniform usamplerBuffer src; 15 | 16 | layout(push_constant) 17 | uniform u_info_t { 18 | uvec2 extent; 19 | } u_info; 20 | 21 | // Format is: 22 | // YYYYYYYY... 23 | // VVVV... 24 | // UUUU... 25 | 26 | float fetchUnorm(usamplerBuffer source, uint offset) { 27 | return unpackUnorm(texelFetch(src, int(offset)).r); 28 | } 29 | 30 | void main() { 31 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 32 | 33 | if (all(lessThan(thread_id.xy, u_info.extent))) { 34 | uvec2 pitch = uvec2(u_info.extent.x, u_info.extent.y); 35 | 36 | uint offset = thread_id.x 37 | + thread_id.y * pitch.x; 38 | 39 | // Fetch a Y, luminance sample. 40 | float y = fetchUnorm(src, offset) - (16 / 255.0); 41 | 42 | // Go into the second plane to get a V, chroma sample 43 | offset = (thread_id.x / 2) 44 | + (thread_id.y / 2) * (pitch.x / 2) 45 | + pitch.x * pitch.y; 46 | 47 | float v = fetchUnorm(src, offset) - (128 / 255.0); 48 | 49 | // Go into the third plane to get a U, chroma sample 50 | offset += (pitch.x / 2) * (pitch.y / 2); 51 | float u = fetchUnorm(src, offset) - (128 / 255.0); 52 | 53 | // TODO: Is this the right color space? 54 | vec4 color = convertBT_709(vec3(y, u, v)); 55 | 56 | imageStore(dst, thread_id.xy, color); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/d3d9/version.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // DLL version information. 4 | VS_VERSION_INFO VERSIONINFO 5 | FILEVERSION 10,0,17763,1 6 | PRODUCTVERSION 10,0,17763,1 7 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 8 | FILEFLAGS 0 9 | FILEOS VOS_NT_WINDOWS32 10 | FILETYPE VFT_DLL 11 | FILESUBTYPE VFT2_UNKNOWN 12 | BEGIN 13 | BLOCK "StringFileInfo" 14 | BEGIN 15 | BLOCK "080904b0" 16 | BEGIN 17 | VALUE "CompanyName", "DXVK" 18 | VALUE "FileDescription", "Direct3D 9 Runtime" 19 | VALUE "FileVersion", "10.0.17763.1 (WinBuild.160101.0800)" 20 | VALUE "InternalName", "D3D9.dll" 21 | VALUE "LegalCopyright", "zlib/libpng license" 22 | VALUE "OriginalFilename", "D3D9.dll" 23 | VALUE "ProductName", "DXVK" 24 | VALUE "ProductVersion", "10.0.17763.1" 25 | END 26 | END 27 | BLOCK "VarFileInfo" 28 | BEGIN 29 | VALUE "Translation", 0x0809, 1200 30 | END 31 | END 32 | -------------------------------------------------------------------------------- /src/dxbc/dxbc_chunk_shex.cpp: -------------------------------------------------------------------------------- 1 | #include "dxbc_chunk_shex.h" 2 | 3 | namespace dxvk { 4 | 5 | DxbcShex::DxbcShex(DxbcReader reader) { 6 | // The shader version and type are stored in a 32-bit unit, 7 | // where the first byte contains the major and minor version 8 | // numbers, and the high word contains the program type. 9 | reader.skip(2); 10 | auto pType = reader.readEnum(); 11 | m_programInfo = DxbcProgramInfo(pType); 12 | 13 | // Read the actual shader code as an array of DWORDs. 14 | auto codeLength = reader.readu32() - 2; 15 | m_code.resize(codeLength); 16 | reader.read(m_code.data(), codeLength * sizeof(uint32_t)); 17 | } 18 | 19 | 20 | DxbcShex::~DxbcShex() { 21 | 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/dxbc/dxbc_chunk_shex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxbc_common.h" 4 | #include "dxbc_decoder.h" 5 | #include "dxbc_reader.h" 6 | 7 | namespace dxvk { 8 | 9 | /** 10 | * \brief Shader code chunk 11 | * 12 | * Stores the DXBC shader code itself, as well 13 | * as some meta info about the shader, i.e. what 14 | * type of shader this is. 15 | */ 16 | class DxbcShex : public RcObject { 17 | 18 | public: 19 | 20 | DxbcShex(DxbcReader reader); 21 | ~DxbcShex(); 22 | 23 | DxbcProgramInfo programInfo() const { 24 | return m_programInfo; 25 | } 26 | 27 | DxbcCodeSlice slice() const { 28 | return DxbcCodeSlice(m_code.data(), 29 | m_code.data() + m_code.size()); 30 | } 31 | 32 | private: 33 | 34 | DxbcProgramInfo m_programInfo; 35 | std::vector m_code; 36 | 37 | }; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/dxbc/dxbc_common.cpp: -------------------------------------------------------------------------------- 1 | #include "dxbc_common.h" 2 | 3 | namespace dxvk { 4 | 5 | VkShaderStageFlagBits DxbcProgramInfo::shaderStage() const { 6 | switch (m_type) { 7 | case DxbcProgramType::PixelShader : return VK_SHADER_STAGE_FRAGMENT_BIT; 8 | case DxbcProgramType::VertexShader : return VK_SHADER_STAGE_VERTEX_BIT; 9 | case DxbcProgramType::GeometryShader : return VK_SHADER_STAGE_GEOMETRY_BIT; 10 | case DxbcProgramType::HullShader : return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; 11 | case DxbcProgramType::DomainShader : return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; 12 | case DxbcProgramType::ComputeShader : return VK_SHADER_STAGE_COMPUTE_BIT; 13 | } 14 | 15 | throw DxvkError("DxbcProgramInfo::shaderStage: Unsupported program type"); 16 | } 17 | 18 | 19 | spv::ExecutionModel DxbcProgramInfo::executionModel() const { 20 | switch (m_type) { 21 | case DxbcProgramType::PixelShader : return spv::ExecutionModelFragment; 22 | case DxbcProgramType::VertexShader : return spv::ExecutionModelVertex; 23 | case DxbcProgramType::GeometryShader : return spv::ExecutionModelGeometry; 24 | case DxbcProgramType::HullShader : return spv::ExecutionModelTessellationControl; 25 | case DxbcProgramType::DomainShader : return spv::ExecutionModelTessellationEvaluation; 26 | case DxbcProgramType::ComputeShader : return spv::ExecutionModelGLCompute; 27 | } 28 | 29 | throw DxvkError("DxbcProgramInfo::executionModel: Unsupported program type"); 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /src/dxbc/dxbc_common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxbc_include.h" 4 | 5 | namespace dxvk { 6 | 7 | /** 8 | * \brief DXBC Program type 9 | * 10 | * Defines the shader stage that a DXBC 11 | * module has been compiled form. 12 | */ 13 | enum class DxbcProgramType : uint16_t { 14 | PixelShader = 0, 15 | VertexShader = 1, 16 | GeometryShader = 2, 17 | HullShader = 3, 18 | DomainShader = 4, 19 | ComputeShader = 5, 20 | }; 21 | 22 | 23 | /** 24 | * \brief DXBC shader info 25 | * 26 | * Stores the shader program type. 27 | */ 28 | class DxbcProgramInfo { 29 | 30 | public: 31 | 32 | DxbcProgramInfo() { } 33 | DxbcProgramInfo(DxbcProgramType type) 34 | : m_type(type) { } 35 | 36 | /** 37 | * \brief Program type 38 | * \returns Program type 39 | */ 40 | DxbcProgramType type() const { 41 | return m_type; 42 | } 43 | 44 | /** 45 | * \brief Vulkan shader stage 46 | * 47 | * The \c VkShaderStageFlagBits constant 48 | * that corresponds to the program type. 49 | * \returns Vulkan shaer stage 50 | */ 51 | VkShaderStageFlagBits shaderStage() const; 52 | 53 | /** 54 | * \brief SPIR-V execution model 55 | * 56 | * The execution model that corresponds 57 | * to the Vulkan shader stage. 58 | * \returns SPIR-V execution model 59 | */ 60 | spv::ExecutionModel executionModel() const; 61 | 62 | private: 63 | 64 | DxbcProgramType m_type = DxbcProgramType::PixelShader; 65 | 66 | }; 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/dxbc/dxbc_header.cpp: -------------------------------------------------------------------------------- 1 | #include "dxbc_header.h" 2 | 3 | namespace dxvk { 4 | 5 | DxbcHeader::DxbcHeader(DxbcReader& reader) { 6 | // FourCC at the start of the file, must be 'DXBC' 7 | DxbcTag fourcc = reader.readTag(); 8 | 9 | if (fourcc != "DXBC") 10 | throw DxvkError("DxbcHeader::DxbcHeader: Invalid fourcc, expected 'DXBC'"); 11 | 12 | // Stuff we don't actually need to store 13 | reader.skip(4 * sizeof(uint32_t)); // Check sum 14 | reader.skip(1 * sizeof(uint32_t)); // Constant 1 15 | reader.skip(1 * sizeof(uint32_t)); // Bytecode length 16 | 17 | // Number of chunks in the file 18 | uint32_t chunkCount = reader.readu32(); 19 | 20 | // Chunk offsets are stored immediately after 21 | for (uint32_t i = 0; i < chunkCount; i++) 22 | m_chunkOffsets.push_back(reader.readu32()); 23 | } 24 | 25 | 26 | DxbcHeader::~DxbcHeader() { 27 | 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/dxbc/dxbc_header.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "dxbc_reader.h" 6 | 7 | namespace dxvk { 8 | 9 | /** 10 | * \brief DXBC header 11 | * 12 | * Stores information about the shader file itself 13 | * and the data chunks stored inside the file. 14 | */ 15 | class DxbcHeader { 16 | 17 | public: 18 | 19 | DxbcHeader(DxbcReader& reader); 20 | ~DxbcHeader(); 21 | 22 | /** 23 | * \brief Number of chunks 24 | * \returns Chunk count 25 | */ 26 | uint32_t numChunks() const { 27 | return m_chunkOffsets.size(); 28 | } 29 | 30 | /** 31 | * \brief Chunk offset 32 | * 33 | * Retrieves the offset of a chunk, in 34 | * bytes, from the start of the file. 35 | * \param [in] chunkId Chunk index 36 | * \returns Byte offset of that chunk 37 | */ 38 | uint32_t chunkOffset(uint32_t chunkId) const { 39 | return m_chunkOffsets.at(chunkId); 40 | } 41 | 42 | private: 43 | 44 | std::vector m_chunkOffsets; 45 | 46 | }; 47 | 48 | } -------------------------------------------------------------------------------- /src/dxbc/dxbc_include.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../dxvk/dxvk_shader.h" 4 | 5 | #include "../util/com/com_guid.h" 6 | #include "../util/com/com_object.h" 7 | #include "../util/com/com_pointer.h" 8 | 9 | #include "../util/log/log.h" 10 | #include "../util/log/log_debug.h" 11 | 12 | #include "../util/rc/util_rc.h" 13 | #include "../util/rc/util_rc_ptr.h" 14 | 15 | #include "../util/util_bit.h" 16 | #include "../util/util_enum.h" 17 | #include "../util/util_error.h" 18 | #include "../util/util_string.h" 19 | -------------------------------------------------------------------------------- /src/dxbc/dxbc_modinfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxbc_options.h" 4 | 5 | namespace dxvk { 6 | 7 | /** 8 | * \brief Tessellation info 9 | * 10 | * Stores the maximum tessellation factor 11 | * to export from tessellation shaders. 12 | */ 13 | struct DxbcTessInfo { 14 | float maxTessFactor; 15 | }; 16 | 17 | /** 18 | * \brief Xfb capture entry 19 | * 20 | * Stores an output variable to capture, 21 | * as well as the buffer to write it to. 22 | */ 23 | struct DxbcXfbEntry { 24 | const char* semanticName; 25 | uint32_t semanticIndex; 26 | uint32_t componentIndex; 27 | uint32_t componentCount; 28 | uint32_t streamId; 29 | uint32_t bufferId; 30 | uint32_t offset; 31 | }; 32 | 33 | /** 34 | * \brief Xfb info 35 | * 36 | * Stores capture entries and output buffer 37 | * strides. This structure must only be 38 | * defined if \c entryCount is non-zero. 39 | */ 40 | struct DxbcXfbInfo { 41 | uint32_t entryCount; 42 | DxbcXfbEntry entries[128]; 43 | uint32_t strides[4]; 44 | int32_t rasterizedStream; 45 | }; 46 | 47 | /** 48 | * \brief Shader module info 49 | * 50 | * Stores information which may affect shader compilation. 51 | * This data can be supplied by the client API implementation. 52 | */ 53 | struct DxbcModuleInfo { 54 | DxbcOptions options; 55 | DxbcTessInfo* tess; 56 | DxbcXfbInfo* xfb; 57 | }; 58 | 59 | } -------------------------------------------------------------------------------- /src/dxbc/dxbc_names.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "dxbc_common.h" 6 | #include "dxbc_enums.h" 7 | 8 | namespace dxvk { 9 | 10 | std::ostream& operator << (std::ostream& os, DxbcOpcode e); 11 | std::ostream& operator << (std::ostream& os, DxbcExtOpcode e); 12 | std::ostream& operator << (std::ostream& os, DxbcOperandType e); 13 | std::ostream& operator << (std::ostream& os, DxbcOperandExt e); 14 | std::ostream& operator << (std::ostream& os, DxbcComponentCount e); 15 | std::ostream& operator << (std::ostream& os, DxbcRegMode e); 16 | std::ostream& operator << (std::ostream& os, DxbcOperandIndexRepresentation e); 17 | std::ostream& operator << (std::ostream& os, DxbcResourceDim e); 18 | std::ostream& operator << (std::ostream& os, DxbcResourceReturnType e); 19 | std::ostream& operator << (std::ostream& os, DxbcRegisterComponentType e); 20 | std::ostream& operator << (std::ostream& os, DxbcInstructionReturnType e); 21 | std::ostream& operator << (std::ostream& os, DxbcSystemValue e); 22 | std::ostream& operator << (std::ostream& os, DxbcProgramType e); 23 | std::ostream& operator << (std::ostream& os, DxbcCustomDataClass e); 24 | std::ostream& operator << (std::ostream& os, DxbcScalarType e); 25 | 26 | } // namespace dxvk 27 | -------------------------------------------------------------------------------- /src/dxbc/dxbc_reader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "dxbc_reader.h" 4 | 5 | namespace dxvk { 6 | 7 | DxbcTag DxbcReader::readTag() { 8 | DxbcTag tag; 9 | this->read(&tag, 4); 10 | return tag; 11 | } 12 | 13 | 14 | std::string DxbcReader::readString() { 15 | std::string result; 16 | 17 | while (m_data[m_pos] != '\0') 18 | result.push_back(m_data[m_pos++]); 19 | 20 | m_pos++; 21 | return result; 22 | } 23 | 24 | 25 | void DxbcReader::read(void* dst, size_t n) { 26 | if (m_pos + n > m_size) 27 | throw DxvkError("DxbcReader::read: Unexpected end of file"); 28 | std::memcpy(dst, m_data + m_pos, n); 29 | m_pos += n; 30 | } 31 | 32 | 33 | void DxbcReader::skip(size_t n) { 34 | if (m_pos + n > m_size) 35 | throw DxvkError("DxbcReader::skip: Unexpected end of file"); 36 | m_pos += n; 37 | } 38 | 39 | 40 | DxbcReader DxbcReader::clone(size_t pos) const { 41 | if (pos > m_size) 42 | throw DxvkError("DxbcReader::clone: Invalid offset"); 43 | return DxbcReader(m_data + pos, m_size - pos); 44 | } 45 | 46 | 47 | DxbcReader DxbcReader::resize(size_t size) const { 48 | if (size > m_size) 49 | throw DxvkError("DxbcReader::resize: Invalid size"); 50 | return DxbcReader(m_data, size, m_pos); 51 | } 52 | 53 | 54 | void DxbcReader::store(std::ostream&& stream) const { 55 | stream.write(m_data, m_size); 56 | } 57 | 58 | } -------------------------------------------------------------------------------- /src/dxbc/dxbc_tag.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxbc_include.h" 4 | 5 | namespace dxvk { 6 | 7 | /** 8 | * \brief Four-character tag 9 | * 10 | * Used to identify chunks in the 11 | * compiled DXBC file by name. 12 | */ 13 | class DxbcTag { 14 | 15 | public: 16 | 17 | DxbcTag() { 18 | for (size_t i = 0; i < 4; i++) 19 | m_chars[i] = '\0'; 20 | } 21 | 22 | DxbcTag(const char* tag) { 23 | for (size_t i = 0; i < 4; i++) 24 | m_chars[i] = tag[i]; 25 | } 26 | 27 | bool operator == (const DxbcTag& other) const { 28 | bool result = true; 29 | for (size_t i = 0; i < 4; i++) 30 | result &= m_chars[i] == other.m_chars[i]; 31 | return result; 32 | } 33 | 34 | bool operator != (const DxbcTag& other) const { 35 | return !this->operator == (other); 36 | } 37 | 38 | const char* operator & () const { return m_chars; } 39 | char* operator & () { return m_chars; } 40 | 41 | private: 42 | 43 | char m_chars[4]; 44 | 45 | }; 46 | 47 | } -------------------------------------------------------------------------------- /src/dxbc/dxbc_util.cpp: -------------------------------------------------------------------------------- 1 | #include "dxbc_util.h" 2 | 3 | namespace dxvk { 4 | 5 | uint32_t primitiveVertexCount(DxbcPrimitive primitive) { 6 | static const std::array s_vertexCounts = { 7 | 0, // Undefined 8 | 1, // Point 9 | 2, // Line 10 | 3, // Triangle 11 | 0, // Undefined 12 | 0, // Undefined 13 | 4, // Line with adjacency 14 | 6, // Triangle with adjacency 15 | }; 16 | 17 | if (primitive >= DxbcPrimitive::Patch1) { 18 | return static_cast(primitive) 19 | - static_cast(DxbcPrimitive::Patch1); 20 | } else { 21 | return s_vertexCounts.at( 22 | static_cast(primitive)); 23 | } 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/dxbc/meson.build: -------------------------------------------------------------------------------- 1 | dxbc_src = files([ 2 | 'dxbc_analysis.cpp', 3 | 'dxbc_chunk_isgn.cpp', 4 | 'dxbc_chunk_shex.cpp', 5 | 'dxbc_common.cpp', 6 | 'dxbc_compiler.cpp', 7 | 'dxbc_defs.cpp', 8 | 'dxbc_decoder.cpp', 9 | 'dxbc_header.cpp', 10 | 'dxbc_module.cpp', 11 | 'dxbc_names.cpp', 12 | 'dxbc_options.cpp', 13 | 'dxbc_reader.cpp', 14 | 'dxbc_util.cpp', 15 | ]) 16 | 17 | dxbc_lib = static_library('dxbc', dxbc_src, 18 | include_directories : [ dxvk_include_path ], 19 | override_options : ['cpp_std='+dxvk_cpp_std]) 20 | 21 | dxbc_dep = declare_dependency( 22 | link_with : [ dxbc_lib ], 23 | include_directories : [ dxvk_include_path ]) 24 | -------------------------------------------------------------------------------- /src/dxgi/dxgi.def: -------------------------------------------------------------------------------- 1 | LIBRARY DXGI.DLL 2 | EXPORTS 3 | CreateDXGIFactory @9 4 | CreateDXGIFactory1 @10 5 | CreateDXGIFactory2 @11 6 | DXGIDeclareAdapterRemovalSupport @16 7 | DXGIGetDebugInterface1 @17 8 | -------------------------------------------------------------------------------- /src/dxgi/dxgi_enums.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxgi_include.h" 4 | 5 | std::ostream& operator << (std::ostream& os, DXGI_FORMAT e); 6 | -------------------------------------------------------------------------------- /src/dxgi/dxgi_include.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //for some reason we need to specify __declspec(dllexport) for MinGW 4 | #if defined(__WINE__) 5 | #define DLLEXPORT __attribute__((visibility("default"))) 6 | #elif defined(_MSC_VER) 7 | #define DLLEXPORT 8 | #else 9 | #define DLLEXPORT __declspec(dllexport) 10 | #endif 11 | 12 | #include "../util/com/com_guid.h" 13 | #include "../util/com/com_object.h" 14 | #include "../util/com/com_pointer.h" 15 | 16 | #include "../util/log/log.h" 17 | #include "../util/log/log_debug.h" 18 | 19 | #include "../util/rc/util_rc.h" 20 | #include "../util/rc/util_rc_ptr.h" 21 | 22 | #include "../util/util_env.h" 23 | #include "../util/util_enum.h" 24 | #include "../util/util_error.h" 25 | #include "../util/util_flags.h" 26 | #include "../util/util_likely.h" 27 | #include "../util/util_math.h" 28 | #include "../util/util_monitor.h" 29 | #include "../util/util_string.h" 30 | 31 | #include 32 | 33 | // For some reason, these are not exposed 34 | #ifndef DXGI_RESOURCE_PRIORITY_NORMAL 35 | #define DXGI_RESOURCE_PRIORITY_MINIMUM (0x28000000) 36 | #define DXGI_RESOURCE_PRIORITY_LOW (0x50000000) 37 | #define DXGI_RESOURCE_PRIORITY_NORMAL (0x78000000) 38 | #define DXGI_RESOURCE_PRIORITY_HIGH (0xa0000000) 39 | #define DXGI_RESOURCE_PRIORITY_MAXIMUM (0xc8000000) 40 | #endif 41 | 42 | #ifndef DXGI_CPU_ACCESS_NONE 43 | #define DXGI_CPU_ACCESS_NONE (0) 44 | #define DXGI_CPU_ACCESS_DYNAMIC (1) 45 | #define DXGI_CPU_ACCESS_READ_WRITE (2) 46 | #define DXGI_CPU_ACCESS_SCRATCH (3) 47 | #define DXGI_CPU_ACCESS_FIELD (0xf) 48 | #endif -------------------------------------------------------------------------------- /src/dxgi/dxgi_monitor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "dxgi_interfaces.h" 7 | 8 | namespace dxvk { 9 | 10 | class DxgiSwapChain; 11 | 12 | class DxgiMonitorInfo : public IDXGIVkMonitorInfo { 13 | 14 | public: 15 | 16 | DxgiMonitorInfo(IUnknown* pParent); 17 | 18 | ~DxgiMonitorInfo(); 19 | 20 | ULONG STDMETHODCALLTYPE AddRef(); 21 | 22 | ULONG STDMETHODCALLTYPE Release(); 23 | 24 | HRESULT STDMETHODCALLTYPE QueryInterface( 25 | REFIID riid, 26 | void** ppvObject); 27 | 28 | HRESULT STDMETHODCALLTYPE InitMonitorData( 29 | HMONITOR hMonitor, 30 | const DXGI_VK_MONITOR_DATA* pData); 31 | 32 | HRESULT STDMETHODCALLTYPE AcquireMonitorData( 33 | HMONITOR hMonitor, 34 | DXGI_VK_MONITOR_DATA** ppData); 35 | 36 | void STDMETHODCALLTYPE ReleaseMonitorData(); 37 | 38 | private: 39 | 40 | IUnknown* m_parent; 41 | 42 | dxvk::mutex m_monitorMutex; 43 | std::unordered_map m_monitorData; 44 | 45 | }; 46 | 47 | 48 | /** 49 | * \brief Queries bits per pixel for a format 50 | * 51 | * The format must be a valid swap chain format. 52 | * \param [in] Format The DXGI format to query 53 | * \returns Bits per pixel for this format 54 | */ 55 | uint32_t GetMonitorFormatBpp( 56 | DXGI_FORMAT Format); 57 | 58 | } -------------------------------------------------------------------------------- /src/dxgi/dxgi_object.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxgi_include.h" 4 | 5 | #include "../util/com/com_private_data.h" 6 | 7 | namespace dxvk { 8 | 9 | template 10 | class DxgiObject : public ComObject { 11 | 12 | public: 13 | 14 | HRESULT STDMETHODCALLTYPE GetPrivateData( 15 | REFGUID Name, 16 | UINT* pDataSize, 17 | void* pData) final { 18 | return m_privateData.getData( 19 | Name, pDataSize, pData); 20 | } 21 | 22 | HRESULT STDMETHODCALLTYPE SetPrivateData( 23 | REFGUID Name, 24 | UINT DataSize, 25 | const void* pData) final { 26 | return m_privateData.setData( 27 | Name, DataSize, pData); 28 | } 29 | 30 | HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( 31 | REFGUID Name, 32 | const IUnknown* pUnknown) final { 33 | return m_privateData.setInterface( 34 | Name, pUnknown); 35 | } 36 | 37 | private: 38 | 39 | ComPrivateData m_privateData; 40 | 41 | }; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/dxgi/dxgi_options.cpp: -------------------------------------------------------------------------------- 1 | #include "dxgi_options.h" 2 | 3 | #include 4 | 5 | namespace dxvk { 6 | 7 | static int32_t parsePciId(const std::string& str) { 8 | if (str.size() != 4) 9 | return -1; 10 | 11 | int32_t id = 0; 12 | 13 | for (size_t i = 0; i < str.size(); i++) { 14 | id *= 16; 15 | 16 | if (str[i] >= '0' && str[i] <= '9') 17 | id += str[i] - '0'; 18 | else if (str[i] >= 'A' && str[i] <= 'F') 19 | id += str[i] - 'A' + 10; 20 | else if (str[i] >= 'a' && str[i] <= 'f') 21 | id += str[i] - 'a' + 10; 22 | else 23 | return -1; 24 | } 25 | 26 | return id; 27 | } 28 | 29 | 30 | DxgiOptions::DxgiOptions(const Config& config) { 31 | // Fetch these as a string representing a hexadecimal number and parse it. 32 | this->customVendorId = parsePciId(config.getOption("dxgi.customVendorId")); 33 | this->customDeviceId = parsePciId(config.getOption("dxgi.customDeviceId")); 34 | this->customDeviceDesc = config.getOption("dxgi.customDeviceDesc", ""); 35 | 36 | // Emulate a UMA device 37 | this->emulateUMA = config.getOption("dxgi.emulateUMA", false); 38 | 39 | // Interpret the memory limits as Megabytes 40 | this->maxDeviceMemory = VkDeviceSize(config.getOption("dxgi.maxDeviceMemory", 0)) << 20; 41 | this->maxSharedMemory = VkDeviceSize(config.getOption("dxgi.maxSharedMemory", 0)) << 20; 42 | 43 | this->nvapiHack = config.getOption("dxgi.nvapiHack", true); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /src/dxgi/dxgi_options.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../util/config/config.h" 4 | 5 | #include "../dxvk/dxvk_include.h" 6 | 7 | #include "dxgi_include.h" 8 | 9 | namespace dxvk { 10 | 11 | /** 12 | * \brief DXGI options 13 | * 14 | * Per-app options that control the 15 | * behaviour of some DXGI classes. 16 | */ 17 | struct DxgiOptions { 18 | DxgiOptions(const Config& config); 19 | 20 | /// Override PCI vendor and device IDs reported to the 21 | /// application. This may make apps think they are running 22 | /// on a different GPU than they do and behave differently. 23 | int32_t customVendorId; 24 | int32_t customDeviceId; 25 | std::string customDeviceDesc; 26 | 27 | /// Override maximum reported VRAM size. This may be 28 | /// useful for some 64-bit games which do not support 29 | /// more than 4 GiB of VRAM. 30 | VkDeviceSize maxDeviceMemory; 31 | VkDeviceSize maxSharedMemory; 32 | 33 | /// Emulate UMA 34 | bool emulateUMA; 35 | 36 | /// Enables nvapi workaround 37 | bool nvapiHack; 38 | }; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/dxgi/meson.build: -------------------------------------------------------------------------------- 1 | dxgi_res = wrc_generator.process('version.rc') 2 | 3 | dxgi_src = [ 4 | 'dxgi_adapter.cpp', 5 | 'dxgi_enums.cpp', 6 | 'dxgi_factory.cpp', 7 | 'dxgi_format.cpp', 8 | 'dxgi_main.cpp', 9 | 'dxgi_monitor.cpp', 10 | 'dxgi_options.cpp', 11 | 'dxgi_output.cpp', 12 | 'dxgi_swapchain.cpp', 13 | ] 14 | 15 | dxgi_dll = shared_library('dxgi'+dll_ext, dxgi_src, dxgi_res, 16 | name_prefix : '', 17 | dependencies : [ dxvk_dep ], 18 | include_directories : dxvk_include_path, 19 | install : true, 20 | vs_module_defs : 'dxgi'+def_spec_ext, 21 | override_options : ['cpp_std='+dxvk_cpp_std]) 22 | 23 | dxgi_dep = declare_dependency( 24 | link_with : [ dxgi_dll ], 25 | include_directories : [ dxvk_include_path ]) 26 | -------------------------------------------------------------------------------- /src/dxgi/version.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // DLL version information. 4 | VS_VERSION_INFO VERSIONINFO 5 | FILEVERSION 10,0,17763,1 6 | PRODUCTVERSION 10,0,17763,1 7 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 8 | FILEFLAGS 0 9 | FILEOS VOS_NT_WINDOWS32 10 | FILETYPE VFT_DLL 11 | FILESUBTYPE VFT2_UNKNOWN 12 | BEGIN 13 | BLOCK "StringFileInfo" 14 | BEGIN 15 | BLOCK "080904b0" 16 | BEGIN 17 | VALUE "CompanyName", "DXVK" 18 | VALUE "FileDescription", "DirectX Graphics Infrastructure" 19 | VALUE "FileVersion", "10.0.17763.1 (WinBuild.160101.0800)" 20 | VALUE "InternalName", "dxgi.dll" 21 | VALUE "LegalCopyright", "zlib/libpng license" 22 | VALUE "OriginalFilename", "dxgi.dll" 23 | VALUE "ProductName", "DXVK" 24 | VALUE "ProductVersion", "10.0.17763.1" 25 | END 26 | END 27 | BLOCK "VarFileInfo" 28 | BEGIN 29 | VALUE "Translation", 0x0809, 1200 30 | END 31 | END 32 | 33 | -------------------------------------------------------------------------------- /src/dxso/dxso_analysis.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxso_modinfo.h" 4 | #include "dxso_decoder.h" 5 | 6 | namespace dxvk { 7 | 8 | struct DxsoAnalysisInfo { 9 | uint32_t bytecodeByteLength; 10 | 11 | bool usesDerivatives = false; 12 | bool usesKill = false; 13 | 14 | std::vector coissues; 15 | }; 16 | 17 | class DxsoAnalyzer { 18 | 19 | public: 20 | 21 | DxsoAnalyzer( 22 | DxsoAnalysisInfo& analysis); 23 | 24 | /** 25 | * \brief Processes a single instruction 26 | * \param [in] ins The instruction 27 | */ 28 | void processInstruction( 29 | const DxsoInstructionContext& ctx); 30 | 31 | void finalize(size_t tokenCount); 32 | 33 | private: 34 | 35 | DxsoAnalysisInfo* m_analysis = nullptr; 36 | 37 | DxsoOpcode m_parentOpcode; 38 | 39 | }; 40 | 41 | } -------------------------------------------------------------------------------- /src/dxso/dxso_code.cpp: -------------------------------------------------------------------------------- 1 | #include "dxso_code.h" 2 | 3 | namespace dxvk { 4 | 5 | DxsoCode::DxsoCode(DxsoReader& reader) { 6 | m_code = 7 | reinterpret_cast(reader.currentPtr()); 8 | } 9 | 10 | const uint32_t* DxsoCodeIter::ptrAt(uint32_t id) const { 11 | return m_ptr + id; 12 | } 13 | 14 | 15 | uint32_t DxsoCodeIter::at(uint32_t id) const { 16 | return m_ptr[id]; 17 | } 18 | 19 | 20 | uint32_t DxsoCodeIter::read() { 21 | return *(m_ptr++); 22 | } 23 | 24 | DxsoCodeIter DxsoCodeIter::skip(uint32_t n) const { 25 | return DxsoCodeIter(m_ptr + n); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /src/dxso/dxso_code.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxso_include.h" 4 | #include "dxso_reader.h" 5 | 6 | #include 7 | #include 8 | 9 | namespace dxvk { 10 | 11 | /** 12 | * \brief DXBC code iterator 13 | * 14 | * Convenient pointer wrapper that allows 15 | * reading the code token stream. 16 | */ 17 | class DxsoCodeIter { 18 | 19 | public: 20 | 21 | DxsoCodeIter( 22 | const uint32_t* ptr) 23 | : m_ptr(ptr) { } 24 | 25 | const uint32_t* ptrAt(uint32_t id) const; 26 | 27 | uint32_t at(uint32_t id) const; 28 | uint32_t read(); 29 | 30 | DxsoCodeIter skip(uint32_t n) const; 31 | 32 | private: 33 | 34 | const uint32_t* m_ptr = nullptr; 35 | 36 | }; 37 | 38 | class DxsoCode { 39 | 40 | public: 41 | 42 | DxsoCode(DxsoReader& reader); 43 | 44 | DxsoCodeIter iter() const { 45 | return DxsoCodeIter(m_code); 46 | } 47 | 48 | private: 49 | 50 | const uint32_t* m_code; 51 | 52 | }; 53 | 54 | } -------------------------------------------------------------------------------- /src/dxso/dxso_common.cpp: -------------------------------------------------------------------------------- 1 | #include "dxso_common.h" 2 | 3 | namespace dxvk { 4 | 5 | VkShaderStageFlagBits DxsoProgramInfo::shaderStage() const { 6 | switch (m_type) { 7 | case DxsoProgramTypes::PixelShader: return VK_SHADER_STAGE_FRAGMENT_BIT; 8 | case DxsoProgramTypes::VertexShader: return VK_SHADER_STAGE_VERTEX_BIT; 9 | default: break; 10 | } 11 | 12 | throw DxvkError("DxsoProgramInfo::shaderStage: Unsupported program type"); 13 | } 14 | 15 | 16 | spv::ExecutionModel DxsoProgramInfo::executionModel() const { 17 | switch (m_type) { 18 | case DxsoProgramTypes::PixelShader: return spv::ExecutionModelFragment; 19 | case DxsoProgramTypes::VertexShader: return spv::ExecutionModelVertex; 20 | default: break; 21 | } 22 | 23 | throw DxvkError("DxsoProgramInfo::executionModel: Unsupported program type"); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/dxso/dxso_ctab.cpp: -------------------------------------------------------------------------------- 1 | #include "dxso_ctab.h" 2 | 3 | namespace dxvk { 4 | 5 | DxsoCtab::DxsoCtab(DxsoReader& reader, uint32_t commentTokenCount) { 6 | m_size = reader.readu32(); 7 | 8 | if (m_size != sizeof(DxsoCtab)) 9 | throw DxvkError("DxsoCtab: ctab size invalid"); 10 | 11 | m_creator = reader.readu32(); 12 | m_version = reader.readu32(); 13 | m_constants = reader.readu32(); 14 | m_constantInfo = reader.readu32(); 15 | m_flags = reader.readu32(); 16 | m_target = reader.readu32(); 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /src/dxso/dxso_ctab.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxso_common.h" 4 | 5 | #include "dxso_reader.h" 6 | 7 | namespace dxvk { 8 | 9 | /** 10 | * \brief DXSO CTAB 11 | * 12 | * Stores meta information about the shader 13 | */ 14 | class DxsoCtab : public RcObject { 15 | 16 | public: 17 | 18 | DxsoCtab(DxsoReader& reader, uint32_t commentTokenCount); 19 | 20 | private: 21 | 22 | uint32_t m_size; 23 | uint32_t m_creator; 24 | uint32_t m_version; 25 | uint32_t m_constants; 26 | uint32_t m_constantInfo; 27 | uint32_t m_flags; 28 | uint32_t m_target; 29 | 30 | }; 31 | 32 | } -------------------------------------------------------------------------------- /src/dxso/dxso_header.cpp: -------------------------------------------------------------------------------- 1 | #include "dxso_header.h" 2 | 3 | namespace dxvk { 4 | 5 | DxsoHeader::DxsoHeader(DxsoReader& reader) { 6 | uint32_t headerToken = reader.readu32(); 7 | 8 | uint32_t headerTypeMask = headerToken & 0xffff0000; 9 | 10 | DxsoProgramType programType; 11 | if (headerTypeMask == 0xffff0000) 12 | programType = DxsoProgramTypes::PixelShader; 13 | else if (headerTypeMask == 0xfffe0000) 14 | programType = DxsoProgramTypes::VertexShader; 15 | else 16 | throw DxvkError("DxsoHeader: invalid header - invalid version"); 17 | 18 | const uint32_t majorVersion = (headerToken >> 8) & 0xff; 19 | const uint32_t minorVersion = headerToken & 0xff; 20 | 21 | m_info = DxsoProgramInfo{ programType, minorVersion, majorVersion }; 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /src/dxso/dxso_header.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxso_common.h" 4 | 5 | #include "dxso_reader.h" 6 | 7 | namespace dxvk { 8 | 9 | /** 10 | * \brief DXSO header 11 | * 12 | * Stores meta information about the shader such 13 | * as the version and the type. 14 | */ 15 | class DxsoHeader { 16 | 17 | public: 18 | 19 | DxsoHeader(DxsoReader& reader); 20 | 21 | const DxsoProgramInfo& info() const { 22 | return m_info; 23 | } 24 | 25 | private: 26 | 27 | DxsoProgramInfo m_info; 28 | 29 | }; 30 | 31 | } -------------------------------------------------------------------------------- /src/dxso/dxso_helpers.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValveSoftware/dxvk/78ef4cfd92cb7f448292aaca83091914ab271257/src/dxso/dxso_helpers.h -------------------------------------------------------------------------------- /src/dxso/dxso_include.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../dxvk/dxvk_shader.h" 4 | 5 | #include "../util/com/com_guid.h" 6 | #include "../util/com/com_object.h" 7 | #include "../util/com/com_pointer.h" 8 | 9 | #include "../util/log/log.h" 10 | #include "../util/log/log_debug.h" 11 | 12 | #include "../util/rc/util_rc.h" 13 | #include "../util/rc/util_rc_ptr.h" 14 | 15 | #include "../util/util_bit.h" 16 | #include "../util/util_enum.h" 17 | #include "../util/util_error.h" 18 | #include "../util/util_string.h" -------------------------------------------------------------------------------- /src/dxso/dxso_isgn.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxso_decoder.h" 4 | 5 | namespace dxvk { 6 | 7 | struct DxsoIsgnEntry { 8 | uint32_t regNumber = 0; 9 | uint32_t slot = 0; 10 | DxsoSemantic semantic = DxsoSemantic{ DxsoUsage::Position, 0 }; 11 | DxsoRegMask mask = IdentityWriteMask; 12 | bool centroid = false; 13 | }; 14 | 15 | struct DxsoIsgn { 16 | std::array< 17 | DxsoIsgnEntry, 18 | 2 * DxsoMaxInterfaceRegs> elems; 19 | uint32_t elemCount = 0; 20 | }; 21 | 22 | struct DxsoDefinedConstant { 23 | uint32_t uboIdx; 24 | 25 | // Only float constants may be indexed. 26 | // So that's the only ones we care about putting in the UBO. 27 | float float32[4]; 28 | }; 29 | 30 | using DxsoDefinedConstants = std::vector; 31 | 32 | struct DxsoShaderMetaInfo { 33 | bool needsConstantCopies = false; 34 | uint32_t maxConstIndexF = 0; 35 | uint32_t maxConstIndexI = 0; 36 | uint32_t maxConstIndexB = 0; 37 | 38 | uint32_t boolConstantMask = 0; 39 | }; 40 | 41 | } -------------------------------------------------------------------------------- /src/dxso/dxso_modinfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxso_options.h" 4 | 5 | namespace dxvk { 6 | 7 | /** 8 | * \brief Shader module info 9 | * 10 | * Stores information which may affect shader compilation. 11 | * This data can be supplied by the client API implementation. 12 | */ 13 | struct DxsoModuleInfo { 14 | DxsoOptions options; 15 | }; 16 | 17 | } -------------------------------------------------------------------------------- /src/dxso/dxso_reader.cpp: -------------------------------------------------------------------------------- 1 | #include "dxso_reader.h" 2 | 3 | #include 4 | 5 | namespace dxvk { 6 | 7 | DxbcTag DxsoReader::readTag() { 8 | DxbcTag tag; 9 | this->read(&tag, 4); 10 | return tag; 11 | } 12 | 13 | void DxsoReader::read(void* dst, size_t n) { 14 | std::memcpy(dst, m_data + m_pos, n); 15 | m_pos += n; 16 | } 17 | 18 | void DxsoReader::skip(size_t n) { 19 | m_pos += n; 20 | } 21 | 22 | void DxsoReader::store(std::ostream && stream, size_t size) const { 23 | stream.write(m_data, size); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/dxso/dxso_reader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxso_include.h" 4 | 5 | #include "../dxbc/dxbc_tag.h" 6 | 7 | #include 8 | 9 | namespace dxvk { 10 | 11 | /** 12 | * \brief DXSO (d3d9) bytecode reader 13 | * 14 | * Holds references to the shader byte code and 15 | * provides methods to read 16 | */ 17 | class DxsoReader { 18 | 19 | public: 20 | 21 | DxsoReader(const char* data) 22 | : DxsoReader(data, 0) { } 23 | 24 | size_t pos() { 25 | return m_pos; 26 | } 27 | 28 | auto readu32() { return this->readNum (); } 29 | auto readf32() { return this->readNum (); } 30 | 31 | DxbcTag readTag(); 32 | 33 | void read(void* dst, size_t n); 34 | 35 | void skip(size_t n); 36 | 37 | void store(std::ostream&& stream, size_t size) const; 38 | 39 | const char* currentPtr() { 40 | return m_data + m_pos; 41 | } 42 | 43 | private: 44 | 45 | DxsoReader(const char* data, size_t pos) 46 | : m_data(data), m_pos(pos) { } 47 | 48 | const char* m_data = nullptr; 49 | size_t m_pos = 0; 50 | 51 | template 52 | T readNum() { 53 | T result; 54 | this->read(&result, sizeof(result)); 55 | return result; 56 | } 57 | 58 | }; 59 | 60 | } -------------------------------------------------------------------------------- /src/dxso/dxso_tables.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxso_enums.h" 4 | 5 | namespace dxvk { 6 | 7 | constexpr uint32_t InvalidOpcodeLength = UINT32_MAX; 8 | 9 | uint32_t DxsoGetDefaultOpcodeLength(DxsoOpcode opcode); 10 | 11 | } -------------------------------------------------------------------------------- /src/dxso/dxso_util.cpp: -------------------------------------------------------------------------------- 1 | #include "dxso_util.h" 2 | 3 | #include "dxso_include.h" 4 | 5 | namespace dxvk { 6 | 7 | dxvk::mutex g_linkerSlotMutex; 8 | uint32_t g_linkerSlotCount = 0; 9 | std::array g_linkerSlots; 10 | 11 | uint32_t RegisterLinkerSlot(DxsoSemantic semantic) { 12 | // Lock, because games could be trying 13 | // to make multiple shaders at a time. 14 | std::lock_guard lock(g_linkerSlotMutex); 15 | 16 | // Need to chose a slot that maps nicely and similarly 17 | // between vertex and pixel shaders 18 | 19 | // Find or map a slot. 20 | uint32_t slot = g_linkerSlotCount; 21 | for (uint32_t j = 0; j < g_linkerSlotCount; j++) { 22 | if (g_linkerSlots[j] == semantic) { 23 | slot = j; 24 | break; 25 | } 26 | } 27 | 28 | if (slot == g_linkerSlotCount) 29 | g_linkerSlots[g_linkerSlotCount++] = semantic; 30 | 31 | return slot; 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /src/dxso/dxso_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "dxso_common.h" 6 | #include "dxso_decoder.h" 7 | 8 | namespace dxvk { 9 | 10 | enum class DxsoBindingType : uint32_t { 11 | ConstantBuffer, 12 | Image, 13 | }; 14 | 15 | enum DxsoConstantBuffers : uint32_t { 16 | VSConstantBuffer = 0, 17 | VSClipPlanes = 1, 18 | VSFixedFunction = 2, 19 | VSVertexBlendData = 3, 20 | VSCount, 21 | 22 | PSConstantBuffer = 0, 23 | PSFixedFunction = 1, 24 | PSShared = 2, 25 | PSCount 26 | }; 27 | 28 | constexpr uint32_t computeResourceSlotId( 29 | DxsoProgramType shaderStage, 30 | DxsoBindingType bindingType, 31 | uint32_t bindingIndex) { 32 | const uint32_t stageOffset = 8 * uint32_t(shaderStage); 33 | 34 | if (bindingType == DxsoBindingType::ConstantBuffer) 35 | return bindingIndex + stageOffset; 36 | else // if (bindingType == DxsoBindingType::Image) 37 | return bindingIndex + stageOffset + (shaderStage == DxsoProgramType::PixelShader ? PSCount : VSCount); 38 | } 39 | 40 | // TODO: Intergrate into compute resource slot ID/refactor all of this? 41 | constexpr uint32_t getSWVPBufferSlot() { 42 | return 27; // From last pixel shader slot, above. 43 | } 44 | 45 | uint32_t RegisterLinkerSlot(DxsoSemantic semantic); 46 | 47 | } -------------------------------------------------------------------------------- /src/dxso/meson.build: -------------------------------------------------------------------------------- 1 | dxso_src = files([ 2 | 'dxso_common.cpp', 3 | 'dxso_options.cpp', 4 | 'dxso_module.cpp', 5 | 'dxso_reader.cpp', 6 | 'dxso_header.cpp', 7 | 'dxso_ctab.cpp', 8 | 'dxso_util.cpp', 9 | 'dxso_code.cpp', 10 | 'dxso_tables.cpp', 11 | 'dxso_decoder.cpp', 12 | 'dxso_analysis.cpp', 13 | 'dxso_compiler.cpp', 14 | 'dxso_enums.cpp' 15 | ]) 16 | 17 | dxso_lib = static_library('dxso', dxso_src, 18 | include_directories : [ dxvk_include_path ], 19 | override_options : ['cpp_std='+dxvk_cpp_std]) 20 | 21 | dxso_dep = declare_dependency( 22 | link_with : [ dxso_lib ], 23 | include_directories : [ dxvk_include_path ]) 24 | -------------------------------------------------------------------------------- /src/dxvk/dxvk_data.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "dxvk_data.h" 4 | 5 | namespace dxvk { 6 | 7 | DxvkDataBuffer:: DxvkDataBuffer() { } 8 | DxvkDataBuffer::DxvkDataBuffer(size_t size) 9 | : m_data(new char[size]), m_size(size) { } 10 | 11 | 12 | DxvkDataBuffer::~DxvkDataBuffer() { 13 | delete[] m_data; 14 | } 15 | 16 | 17 | DxvkDataSlice DxvkDataBuffer::alloc(size_t n) { 18 | const size_t offset = m_offset; 19 | 20 | if (offset + n <= m_size) { 21 | m_offset += align(n, CACHE_LINE_SIZE); 22 | return DxvkDataSlice(this, offset, n); 23 | } return DxvkDataSlice(); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/dxvk/dxvk_device_filter.cpp: -------------------------------------------------------------------------------- 1 | #include "dxvk_device_filter.h" 2 | 3 | namespace dxvk { 4 | 5 | DxvkDeviceFilter::DxvkDeviceFilter(DxvkDeviceFilterFlags flags) 6 | : m_flags(flags) { 7 | m_matchDeviceName = env::getEnvVar("DXVK_FILTER_DEVICE_NAME"); 8 | 9 | if (m_matchDeviceName.size() != 0) 10 | m_flags.set(DxvkDeviceFilterFlag::MatchDeviceName); 11 | } 12 | 13 | 14 | DxvkDeviceFilter::~DxvkDeviceFilter() { 15 | 16 | } 17 | 18 | 19 | bool DxvkDeviceFilter::testAdapter(const VkPhysicalDeviceProperties& properties) const { 20 | if (properties.apiVersion < VK_MAKE_VERSION(1, 1, 0)) { 21 | Logger::warn(str::format("Skipping Vulkan 1.0 adapter: ", properties.deviceName)); 22 | return false; 23 | } 24 | 25 | if (m_flags.test(DxvkDeviceFilterFlag::MatchDeviceName)) { 26 | if (std::string(properties.deviceName).find(m_matchDeviceName) == std::string::npos) 27 | return false; 28 | } 29 | 30 | if (m_flags.test(DxvkDeviceFilterFlag::SkipCpuDevices)) { 31 | if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) { 32 | Logger::warn(str::format("Skipping CPU adapter: ", properties.deviceName)); 33 | return false; 34 | } 35 | } 36 | 37 | return true; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/dxvk/dxvk_device_filter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxvk_adapter.h" 4 | 5 | namespace dxvk { 6 | 7 | /** 8 | * \brief Device filter flags 9 | * 10 | * The device filter flags specify which device 11 | * properties are considered when testing adapters. 12 | * If no flags are set, all devices pass the test. 13 | */ 14 | enum class DxvkDeviceFilterFlag { 15 | MatchDeviceName = 0, 16 | SkipCpuDevices = 1, 17 | }; 18 | 19 | using DxvkDeviceFilterFlags = Flags; 20 | 21 | 22 | /** 23 | * \brief DXVK device filter 24 | * 25 | * Used to select specific Vulkan devices to use 26 | * with DXVK. This may be useful for games which 27 | * do not offer an option to select the correct 28 | * device. 29 | */ 30 | class DxvkDeviceFilter { 31 | 32 | public: 33 | 34 | DxvkDeviceFilter(DxvkDeviceFilterFlags flags); 35 | ~DxvkDeviceFilter(); 36 | 37 | /** 38 | * \brief Tests an adapter 39 | * 40 | * \param [in] properties Adapter properties 41 | * \returns \c true if the test passes 42 | */ 43 | bool testAdapter( 44 | const VkPhysicalDeviceProperties& properties) const; 45 | 46 | private: 47 | 48 | DxvkDeviceFilterFlags m_flags; 49 | 50 | std::string m_matchDeviceName; 51 | 52 | }; 53 | 54 | } -------------------------------------------------------------------------------- /src/dxvk/dxvk_hash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace dxvk { 6 | 7 | struct DxvkEq { 8 | template 9 | size_t operator () (const T& a, const T& b) const { 10 | return a.eq(b); 11 | } 12 | }; 13 | 14 | struct DxvkHash { 15 | template 16 | size_t operator () (const T& object) const { 17 | return object.hash(); 18 | } 19 | }; 20 | 21 | class DxvkHashState { 22 | 23 | public: 24 | 25 | void add(size_t hash) { 26 | m_value ^= hash + 0x9e3779b9 27 | + (m_value << 6) 28 | + (m_value >> 2); 29 | } 30 | 31 | operator size_t () const { 32 | return m_value; 33 | } 34 | 35 | private: 36 | 37 | size_t m_value = 0; 38 | 39 | }; 40 | 41 | } -------------------------------------------------------------------------------- /src/dxvk/dxvk_include.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../util/log/log.h" 4 | #include "../util/log/log_debug.h" 5 | 6 | #include "../util/util_env.h" 7 | #include "../util/util_error.h" 8 | #include "../util/util_flags.h" 9 | #include "../util/util_likely.h" 10 | #include "../util/util_math.h" 11 | #include "../util/util_small_vector.h" 12 | #include "../util/util_string.h" 13 | 14 | #include "../util/rc/util_rc.h" 15 | #include "../util/rc/util_rc_ptr.h" 16 | 17 | #include "../util/sha1/sha1_util.h" 18 | 19 | #include "../util/sync/sync_signal.h" 20 | #include "../util/sync/sync_spinlock.h" 21 | #include "../util/sync/sync_ticketlock.h" 22 | 23 | #include "../vulkan/vulkan_loader.h" 24 | #include "../vulkan/vulkan_names.h" 25 | #include "../vulkan/vulkan_util.h" 26 | -------------------------------------------------------------------------------- /src/dxvk/dxvk_lifetime.cpp: -------------------------------------------------------------------------------- 1 | #include "dxvk_lifetime.h" 2 | 3 | namespace dxvk { 4 | 5 | DxvkLifetimeTracker:: DxvkLifetimeTracker() { } 6 | DxvkLifetimeTracker::~DxvkLifetimeTracker() { } 7 | 8 | 9 | void DxvkLifetimeTracker::reset() { 10 | for (const auto& resource : m_resources) 11 | resource.first->release(resource.second); 12 | m_resources.clear(); 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /src/dxvk/dxvk_lifetime.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "dxvk_resource.h" 6 | 7 | namespace dxvk { 8 | 9 | /** 10 | * \brief DXVK lifetime tracker 11 | * 12 | * Maintains references to a set of resources. This is 13 | * used to guarantee that resources are not destroyed 14 | * or otherwise accessed in an unsafe manner until the 15 | * device has finished using them. 16 | */ 17 | class DxvkLifetimeTracker { 18 | 19 | public: 20 | 21 | DxvkLifetimeTracker(); 22 | ~DxvkLifetimeTracker(); 23 | 24 | /** 25 | * \brief Adds a resource to track 26 | * \param [in] rc The resource to track 27 | */ 28 | template 29 | void trackResource(Rc&& rc) { 30 | rc->acquire(Access); 31 | m_resources.emplace_back(std::move(rc), Access); 32 | } 33 | 34 | /** 35 | * \brief Resets the command list 36 | * 37 | * Called automatically by the device when 38 | * the command list has completed execution. 39 | */ 40 | void reset(); 41 | 42 | private: 43 | 44 | std::vector, DxvkAccess>> m_resources; 45 | 46 | }; 47 | 48 | } -------------------------------------------------------------------------------- /src/dxvk/dxvk_limits.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxvk_include.h" 4 | 5 | namespace dxvk { 6 | 7 | enum DxvkLimits : size_t { 8 | MaxNumRenderTargets = 8, 9 | MaxNumVertexAttributes = 32, 10 | MaxNumVertexBindings = 32, 11 | MaxNumXfbBuffers = 4, 12 | MaxNumXfbStreams = 4, 13 | MaxNumViewports = 16, 14 | MaxNumResourceSlots = 1216, 15 | MaxNumActiveBindings = 384, 16 | MaxNumQueuedCommandBuffers = 18, 17 | MaxNumQueryCountPerPool = 128, 18 | MaxNumSpecConstants = 12, 19 | MaxUniformBufferSize = 65536, 20 | MaxVertexBindingStride = 2048, 21 | MaxPushConstantSize = 128, 22 | }; 23 | 24 | } -------------------------------------------------------------------------------- /src/dxvk/dxvk_main.cpp: -------------------------------------------------------------------------------- 1 | #include "dxvk_main.h" 2 | 3 | namespace dxvk { 4 | 5 | } -------------------------------------------------------------------------------- /src/dxvk/dxvk_main.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../util/log/log.h" 4 | 5 | 6 | namespace dxvk { 7 | 8 | } -------------------------------------------------------------------------------- /src/dxvk/dxvk_openxr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "dxvk_extension_provider.h" 7 | 8 | namespace dxvk { 9 | 10 | class DxvkInstance; 11 | 12 | /** 13 | * \brief OpenXR instance 14 | * 15 | * Loads OpenXR to provide access to Vulkan extension queries. 16 | */ 17 | class DxvkXrProvider : public DxvkExtensionProvider { 18 | 19 | public: 20 | 21 | DxvkXrProvider(); 22 | ~DxvkXrProvider(); 23 | 24 | std::string_view getName(); 25 | 26 | DxvkNameSet getInstanceExtensions(); 27 | 28 | DxvkNameSet getDeviceExtensions( 29 | uint32_t adapterId); 30 | 31 | void initInstanceExtensions(); 32 | 33 | void initDeviceExtensions( 34 | const DxvkInstance* instance); 35 | 36 | static DxvkXrProvider s_instance; 37 | 38 | private: 39 | 40 | dxvk::mutex m_mutex; 41 | HMODULE m_wineOxr = nullptr; 42 | 43 | bool m_loadedOxrApi = false; 44 | bool m_initializedInsExt = false; 45 | bool m_initializedDevExt = false; 46 | 47 | DxvkNameSet m_insExtensions; 48 | DxvkNameSet m_devExtensions; 49 | 50 | DxvkNameSet queryInstanceExtensions() const; 51 | 52 | DxvkNameSet queryDeviceExtensions() const; 53 | 54 | DxvkNameSet parseExtensionList( 55 | const std::string& str) const; 56 | 57 | bool loadFunctions(); 58 | 59 | void shutdown(); 60 | 61 | HMODULE loadLibrary(); 62 | 63 | void freeLibrary(); 64 | 65 | void* getSym(const char* sym); 66 | 67 | }; 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/dxvk/dxvk_options.cpp: -------------------------------------------------------------------------------- 1 | #include "dxvk_options.h" 2 | 3 | namespace dxvk { 4 | 5 | DxvkOptions::DxvkOptions(const Config& config) { 6 | enableStateCache = config.getOption ("dxvk.enableStateCache", true); 7 | enableOpenVR = config.getOption ("dxvk.enableOpenVR", true); 8 | enableOpenXR = config.getOption ("dxvk.enableOpenXR", true); 9 | numCompilerThreads = config.getOption ("dxvk.numCompilerThreads", 0); 10 | useRawSsbo = config.getOption("dxvk.useRawSsbo", Tristate::Auto); 11 | halveNvidiaHVVHeap = config.getOption("dxvk.halveNvidiaHVVHeap", Tristate::Auto); 12 | hud = config.getOption("dxvk.hud", ""); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/dxvk/dxvk_options.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../util/config/config.h" 4 | 5 | namespace dxvk { 6 | 7 | struct DxvkOptions { 8 | DxvkOptions() { } 9 | DxvkOptions(const Config& config); 10 | 11 | /// Enable state cache 12 | bool enableStateCache; 13 | 14 | /// Enables OpenVR loading 15 | bool enableOpenVR; 16 | 17 | /// Enables OpenXR loading 18 | bool enableOpenXR; 19 | 20 | /// Number of compiler threads 21 | /// when using the state cache 22 | int32_t numCompilerThreads; 23 | 24 | /// Shader-related options 25 | Tristate useRawSsbo; 26 | 27 | /// Workaround for NVIDIA driver 28 | /// bug 3114283. Cut usable HVV 29 | /// (Host-Visible Vidmem) heap 30 | /// in half to avoid crash 31 | Tristate halveNvidiaHVVHeap; 32 | 33 | /// HUD elements 34 | std::string hud; 35 | }; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/dxvk/dxvk_pipecache.cpp: -------------------------------------------------------------------------------- 1 | #include "dxvk_pipecache.h" 2 | 3 | namespace dxvk { 4 | 5 | DxvkPipelineCache::DxvkPipelineCache( 6 | const Rc& vkd) 7 | : m_vkd(vkd) { 8 | VkPipelineCacheCreateInfo info; 9 | info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 10 | info.pNext = nullptr; 11 | info.flags = 0; 12 | info.initialDataSize = 0; 13 | info.pInitialData = nullptr; 14 | 15 | if (m_vkd->vkCreatePipelineCache(m_vkd->device(), 16 | &info, nullptr, &m_handle) != VK_SUCCESS) 17 | throw DxvkError("DxvkPipelineCache: Failed to create cache"); 18 | } 19 | 20 | 21 | DxvkPipelineCache::~DxvkPipelineCache() { 22 | m_vkd->vkDestroyPipelineCache( 23 | m_vkd->device(), m_handle, nullptr); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/dxvk/dxvk_pipecache.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "dxvk_include.h" 8 | 9 | #include "../util/sha1/sha1_util.h" 10 | #include "../util/util_env.h" 11 | #include "../util/util_time.h" 12 | 13 | namespace dxvk { 14 | 15 | /** 16 | * \brief Pipeline cache 17 | * 18 | * Allows the Vulkan implementation to 19 | * re-use previously compiled pipelines. 20 | */ 21 | class DxvkPipelineCache : public RcObject { 22 | 23 | public: 24 | 25 | DxvkPipelineCache(const Rc& vkd); 26 | ~DxvkPipelineCache(); 27 | 28 | /** 29 | * \brief Pipeline cache handle 30 | * \returns Pipeline cache handle 31 | */ 32 | VkPipelineCache handle() const { 33 | return m_handle; 34 | } 35 | 36 | private: 37 | 38 | Rc m_vkd; 39 | VkPipelineCache m_handle; 40 | 41 | }; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/dxvk/dxvk_platform_exts.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxvk_extension_provider.h" 4 | 5 | namespace dxvk { 6 | 7 | class DxvkPlatformExts : public DxvkExtensionProvider { 8 | 9 | public: 10 | 11 | std::string_view getName(); 12 | 13 | DxvkNameSet getInstanceExtensions(); 14 | 15 | DxvkNameSet getDeviceExtensions( 16 | uint32_t adapterId); 17 | 18 | void initInstanceExtensions(); 19 | 20 | void initDeviceExtensions( 21 | const DxvkInstance* instance); 22 | 23 | static DxvkPlatformExts s_instance; 24 | }; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/dxvk/dxvk_resource.cpp: -------------------------------------------------------------------------------- 1 | #include "dxvk_resource.h" 2 | 3 | namespace dxvk { 4 | 5 | DxvkResource::~DxvkResource() { 6 | 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /src/dxvk/dxvk_shader_key.cpp: -------------------------------------------------------------------------------- 1 | #include "dxvk_shader_key.h" 2 | 3 | namespace dxvk { 4 | 5 | DxvkShaderKey::DxvkShaderKey() 6 | : m_type(0), 7 | m_sha1(Sha1Hash::compute(nullptr, 0)) { } 8 | 9 | 10 | std::string DxvkShaderKey::toString() const { 11 | const char* prefix = nullptr; 12 | 13 | switch (m_type) { 14 | case VK_SHADER_STAGE_VERTEX_BIT: prefix = "VS_"; break; 15 | case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: prefix = "TCS_"; break; 16 | case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: prefix = "TES_"; break; 17 | case VK_SHADER_STAGE_GEOMETRY_BIT: prefix = "GS_"; break; 18 | case VK_SHADER_STAGE_FRAGMENT_BIT: prefix = "FS_"; break; 19 | case VK_SHADER_STAGE_COMPUTE_BIT: prefix = "CS_"; break; 20 | default: prefix = ""; 21 | } 22 | 23 | return str::format(prefix, m_sha1.toString()); 24 | } 25 | 26 | 27 | size_t DxvkShaderKey::hash() const { 28 | DxvkHashState result; 29 | result.add(uint32_t(m_type)); 30 | 31 | for (uint32_t i = 0; i < 5; i++) 32 | result.add(m_sha1.dword(i)); 33 | 34 | return result; 35 | } 36 | 37 | 38 | bool DxvkShaderKey::eq(const DxvkShaderKey& key) const { 39 | return m_type == key.m_type 40 | && m_sha1 == key.m_sha1; 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /src/dxvk/dxvk_signal.cpp: -------------------------------------------------------------------------------- 1 | #include "dxvk_signal.h" 2 | 3 | namespace dxvk { 4 | 5 | DxvkSignalTracker::DxvkSignalTracker() { 6 | 7 | } 8 | 9 | 10 | DxvkSignalTracker::~DxvkSignalTracker() { 11 | 12 | } 13 | 14 | 15 | void DxvkSignalTracker::add(const Rc& signal, uint64_t value) { 16 | m_signals.push_back({ signal, value }); 17 | } 18 | 19 | 20 | void DxvkSignalTracker::notify() { 21 | for (const auto& pair : m_signals) 22 | pair.first->signal(pair.second); 23 | } 24 | 25 | 26 | void DxvkSignalTracker::reset() { 27 | m_signals.clear(); 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/dxvk/dxvk_signal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "dxvk_include.h" 4 | 5 | namespace dxvk { 6 | 7 | /** 8 | * \brief Signal tracker 9 | */ 10 | class DxvkSignalTracker { 11 | 12 | public: 13 | 14 | DxvkSignalTracker(); 15 | ~DxvkSignalTracker(); 16 | 17 | /** 18 | * \brief Adds a signal to track 19 | * 20 | * \param [in] signal The signal 21 | * \param [in] value Target value 22 | */ 23 | void add(const Rc& signal, uint64_t value); 24 | 25 | /** 26 | * \brief Notifies tracked signals 27 | */ 28 | void notify(); 29 | 30 | /** 31 | * \brief Resets signal tracker 32 | */ 33 | void reset(); 34 | 35 | private: 36 | 37 | std::vector, uint64_t>> m_signals; 38 | 39 | }; 40 | 41 | } -------------------------------------------------------------------------------- /src/dxvk/dxvk_spec_const.cpp: -------------------------------------------------------------------------------- 1 | #include "dxvk_spec_const.h" 2 | 3 | namespace dxvk { 4 | 5 | DxvkSpecConstants::DxvkSpecConstants() { 6 | 7 | } 8 | 9 | 10 | DxvkSpecConstants::~DxvkSpecConstants() { 11 | 12 | } 13 | 14 | 15 | VkSpecializationInfo DxvkSpecConstants::getSpecInfo() const { 16 | VkSpecializationInfo specInfo; 17 | specInfo.mapEntryCount = m_map.size(); 18 | specInfo.pMapEntries = m_map.data(); 19 | specInfo.dataSize = m_data.size() * sizeof(uint32_t); 20 | specInfo.pData = m_data.data(); 21 | return specInfo; 22 | } 23 | 24 | 25 | void DxvkSpecConstants::setAsUint32(uint32_t specId, uint32_t value) { 26 | uint32_t index = m_data.size(); 27 | m_data.push_back(value); 28 | 29 | VkSpecializationMapEntry mapEntry; 30 | mapEntry.constantID = specId; 31 | mapEntry.offset = sizeof(uint32_t) * index; 32 | mapEntry.size = sizeof(uint32_t); 33 | m_map.push_back(mapEntry); 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /src/dxvk/dxvk_staging.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "dxvk_buffer.h" 6 | 7 | namespace dxvk { 8 | 9 | class DxvkDevice; 10 | 11 | /** 12 | * \brief Staging data allocator 13 | * 14 | * Allocates buffer slices for resource uploads, 15 | * while trying to keep the number of allocations 16 | * but also the amount of allocated memory low. 17 | */ 18 | class DxvkStagingDataAlloc { 19 | constexpr static VkDeviceSize MaxBufferSize = 1 << 25; // 32 MiB 20 | constexpr static uint32_t MaxBufferCount = 2; 21 | public: 22 | 23 | DxvkStagingDataAlloc(const Rc& device); 24 | 25 | ~DxvkStagingDataAlloc(); 26 | 27 | /** 28 | * \brief Alloctaes a staging buffer slice 29 | * 30 | * \param [in] align Alignment of the allocation 31 | * \param [in] size Size of the allocation 32 | * \returns Staging buffer slice 33 | */ 34 | DxvkBufferSlice alloc(VkDeviceSize align, VkDeviceSize size); 35 | 36 | /** 37 | * \brief Deletes all staging buffers 38 | * 39 | * Destroys allocated buffers and 40 | * releases all buffer memory. 41 | */ 42 | void trim(); 43 | 44 | private: 45 | 46 | Rc m_device; 47 | Rc m_buffer; 48 | VkDeviceSize m_offset = 0; 49 | 50 | std::queue> m_buffers; 51 | 52 | Rc createBuffer(VkDeviceSize size); 53 | 54 | }; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/dxvk/dxvk_stats.cpp: -------------------------------------------------------------------------------- 1 | #include "dxvk_stats.h" 2 | 3 | namespace dxvk { 4 | 5 | DxvkStatCounters::DxvkStatCounters() { 6 | this->reset(); 7 | } 8 | 9 | 10 | DxvkStatCounters::~DxvkStatCounters() { 11 | 12 | } 13 | 14 | 15 | DxvkStatCounters DxvkStatCounters::diff(const DxvkStatCounters& other) const { 16 | DxvkStatCounters result; 17 | for (size_t i = 0; i < m_counters.size(); i++) 18 | result.m_counters[i] = m_counters[i] - other.m_counters[i]; 19 | return result; 20 | } 21 | 22 | 23 | void DxvkStatCounters::merge(const DxvkStatCounters& other) { 24 | for (size_t i = 0; i < m_counters.size(); i++) 25 | m_counters[i] += other.m_counters[i]; 26 | } 27 | 28 | 29 | void DxvkStatCounters::reset() { 30 | for (size_t i = 0; i < m_counters.size(); i++) 31 | m_counters[i] = 0; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/dxvk/hud/dxvk_hud_font.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace dxvk::hud { 6 | 7 | struct HudGlyph { 8 | uint32_t codePoint; 9 | int32_t x; 10 | int32_t y; 11 | int32_t w; 12 | int32_t h; 13 | int32_t originX; 14 | int32_t originY; 15 | }; 16 | 17 | struct HudFont { 18 | int32_t size; 19 | uint32_t width; 20 | uint32_t height; 21 | uint32_t falloff; 22 | uint32_t advance; 23 | uint32_t charCount; 24 | 25 | const HudGlyph* glyphs; 26 | const uint8_t* texture; 27 | }; 28 | 29 | extern const HudFont g_hudFont; 30 | 31 | } -------------------------------------------------------------------------------- /src/dxvk/hud/shaders/hud_line_frag.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(constant_id = 1225) const bool srgbSwapchain = false; 4 | 5 | layout(location = 0) in vec4 v_color; 6 | layout(location = 0) out vec4 o_color; 7 | 8 | vec3 linearToSrgb(vec3 color) { 9 | bvec3 isLo = lessThanEqual(color, vec3(0.0031308f)); 10 | 11 | vec3 loPart = color * 12.92f; 12 | vec3 hiPart = pow(color, vec3(5.0f / 12.0f)) * 1.055f - 0.055f; 13 | return mix(hiPart, loPart, isLo); 14 | } 15 | 16 | void main() { 17 | o_color = vec4( 18 | v_color.rgb * v_color.a, 19 | v_color.a); 20 | 21 | if (!srgbSwapchain) 22 | o_color.rgb = linearToSrgb(o_color.rgb); 23 | } -------------------------------------------------------------------------------- /src/dxvk/hud/shaders/hud_line_vert.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec2 v_position; 4 | layout(location = 1) in vec4 v_color; 5 | 6 | layout(location = 0) out vec4 o_color; 7 | 8 | void main() { 9 | o_color = v_color; 10 | 11 | vec2 pos = 2.0f * v_position - 1.0f; 12 | gl_Position = vec4(pos, 0.0f, 1.0f); 13 | } -------------------------------------------------------------------------------- /src/dxvk/hud/shaders/hud_text_frag.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(constant_id = 1225) const bool srgbSwapchain = false; 4 | 5 | layout(set = 0, binding = 0) uniform sampler2D s_font; 6 | 7 | layout(location = 0) in vec2 v_texcoord; 8 | layout(location = 1) in vec4 v_color; 9 | 10 | layout(location = 0) out vec4 o_color; 11 | 12 | vec3 linearToSrgb(vec3 color) { 13 | bvec3 isLo = lessThanEqual(color, vec3(0.0031308f)); 14 | 15 | vec3 loPart = color * 12.92f; 16 | vec3 hiPart = pow(color, vec3(5.0f / 12.0f)) * 1.055f - 0.055f; 17 | return mix(hiPart, loPart, isLo); 18 | } 19 | 20 | float sampleAlpha(float alpha_bias, float dist_range) { 21 | float value = textureLod(s_font, v_texcoord, 0).r + alpha_bias - 0.5f; 22 | float dist = value * dot(vec2(dist_range, dist_range), 1.0f / fwidth(v_texcoord.xy)); 23 | return clamp(dist + 0.5f, 0.0f, 1.0f); 24 | } 25 | 26 | void main() { 27 | float r_alpha_center = sampleAlpha(0.0f, 5.0f); 28 | float r_alpha_shadow = sampleAlpha(0.3f, 5.0f); 29 | 30 | vec4 r_center = vec4(v_color.rgb, v_color.a * r_alpha_center); 31 | vec4 r_shadow = vec4(0.0f, 0.0f, 0.0f, r_alpha_shadow); 32 | 33 | o_color = mix(r_shadow, r_center, r_alpha_center); 34 | o_color.rgb *= o_color.a; 35 | 36 | if (!srgbSwapchain) 37 | o_color.rgb = linearToSrgb(o_color.rgb); 38 | } 39 | -------------------------------------------------------------------------------- /src/dxvk/hud/shaders/hud_text_vert.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec2 v_position; 4 | layout(location = 1) in uvec2 v_texcoord; 5 | layout(location = 2) in vec4 v_color; 6 | 7 | layout(location = 0) out vec2 o_texcoord; 8 | layout(location = 1) out vec4 o_color; 9 | 10 | void main() { 11 | o_texcoord = vec2(v_texcoord); 12 | o_color = v_color; 13 | 14 | vec2 pos = 2.0f * v_position - 1.0f; 15 | gl_Position = vec4(pos, 0.0f, 1.0f); 16 | } -------------------------------------------------------------------------------- /src/dxvk/platform/dxvk_win32_exts.cpp: -------------------------------------------------------------------------------- 1 | #include "../dxvk_platform_exts.h" 2 | 3 | namespace dxvk { 4 | 5 | DxvkPlatformExts DxvkPlatformExts::s_instance; 6 | 7 | std::string_view DxvkPlatformExts::getName() { 8 | return "Win32 WSI"; 9 | } 10 | 11 | 12 | DxvkNameSet DxvkPlatformExts::getInstanceExtensions() { 13 | DxvkNameSet names; 14 | names.add(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); 15 | 16 | return names; 17 | } 18 | 19 | 20 | DxvkNameSet DxvkPlatformExts::getDeviceExtensions( 21 | uint32_t adapterId) { 22 | return DxvkNameSet(); 23 | } 24 | 25 | 26 | void DxvkPlatformExts::initInstanceExtensions() { 27 | 28 | } 29 | 30 | 31 | void DxvkPlatformExts::initDeviceExtensions( 32 | const DxvkInstance* instance) { 33 | 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_blit_frag_1d.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(set = 0, binding = 0) 4 | uniform sampler1DArray s_texture; 5 | 6 | layout(location = 0) in vec2 i_pos; 7 | layout(location = 0) out vec4 o_color; 8 | 9 | layout(push_constant) 10 | uniform push_block { 11 | vec3 p_src_coord0; 12 | vec3 p_src_coord1; 13 | uint p_layer_count; 14 | }; 15 | 16 | void main() { 17 | float coord = mix(p_src_coord0.x, p_src_coord1.x, i_pos.x); 18 | o_color = texture(s_texture, vec2(coord, gl_Layer)); 19 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_blit_frag_2d.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(set = 0, binding = 0) 4 | uniform sampler2DArray s_texture; 5 | 6 | layout(location = 0) in vec2 i_pos; 7 | layout(location = 0) out vec4 o_color; 8 | 9 | layout(push_constant) 10 | uniform push_block { 11 | vec3 p_src_coord0; 12 | vec3 p_src_coord1; 13 | uint p_layer_count; 14 | }; 15 | 16 | void main() { 17 | vec2 coord = mix(p_src_coord0.xy, p_src_coord1.xy, i_pos); 18 | o_color = texture(s_texture, vec3(coord, gl_Layer)); 19 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_blit_frag_3d.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(set = 0, binding = 0) 4 | uniform sampler3D s_texture; 5 | 6 | layout(location = 0) in vec2 i_pos; 7 | layout(location = 0) out vec4 o_color; 8 | 9 | layout(push_constant) 10 | uniform push_block { 11 | vec3 p_src_coord0; 12 | vec3 p_src_coord1; 13 | uint p_layer_count; 14 | }; 15 | 16 | void main() { 17 | vec3 coord = mix(p_src_coord0, p_src_coord1, 18 | vec3(i_pos, (float(gl_Layer) + 0.5f) / float(p_layer_count))); 19 | o_color = texture(s_texture, coord); 20 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_clear_buffer_f.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 128, 5 | local_size_y = 1, 6 | local_size_z = 1) in; 7 | 8 | layout(binding = 0) 9 | writeonly uniform imageBuffer dst; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | vec4 clear_value; 14 | ivec4 dst_offset; 15 | ivec4 dst_extent; 16 | } u_info; 17 | 18 | void main() { 19 | int thread_id = int(gl_GlobalInvocationID.x); 20 | 21 | if (thread_id < u_info.dst_extent.x) { 22 | imageStore(dst, 23 | u_info.dst_offset.x + thread_id, 24 | u_info.clear_value); 25 | } 26 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_clear_buffer_u.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 128, 5 | local_size_y = 1, 6 | local_size_z = 1) in; 7 | 8 | layout(binding = 0) 9 | writeonly uniform uimageBuffer dst; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | uvec4 clear_value; 14 | ivec4 dst_offset; 15 | ivec4 dst_extent; 16 | } u_info; 17 | 18 | void main() { 19 | int thread_id = int(gl_GlobalInvocationID.x); 20 | 21 | if (thread_id < u_info.dst_extent.x) { 22 | imageStore(dst, 23 | u_info.dst_offset.x + thread_id, 24 | u_info.clear_value); 25 | } 26 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_clear_image1d_f.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 64, 5 | local_size_y = 1, 6 | local_size_z = 1) in; 7 | 8 | layout(binding = 0) 9 | writeonly uniform image1D dst; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | vec4 clear_value; 14 | ivec4 dst_offset; 15 | ivec4 dst_extent; 16 | } u_info; 17 | 18 | void main() { 19 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 20 | 21 | if (thread_id.x < u_info.dst_extent.x) { 22 | imageStore(dst, 23 | u_info.dst_offset.x + thread_id.x, 24 | u_info.clear_value); 25 | } 26 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_clear_image1d_u.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 64, 5 | local_size_y = 1, 6 | local_size_z = 1) in; 7 | 8 | layout(binding = 0) 9 | writeonly uniform uimage1D dst; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | uvec4 clear_value; 14 | ivec4 dst_offset; 15 | ivec4 dst_extent; 16 | } u_info; 17 | 18 | void main() { 19 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 20 | 21 | if (thread_id.x < u_info.dst_extent.x) { 22 | imageStore(dst, 23 | u_info.dst_offset.x + thread_id.x, 24 | u_info.clear_value); 25 | } 26 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_clear_image1darr_f.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 64, 5 | local_size_y = 1, 6 | local_size_z = 1) in; 7 | 8 | layout(binding = 0) 9 | writeonly uniform image1DArray dst; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | vec4 clear_value; 14 | ivec4 dst_offset; 15 | ivec4 dst_extent; 16 | } u_info; 17 | 18 | void main() { 19 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 20 | 21 | if (thread_id.x < u_info.dst_extent.x) { 22 | imageStore(dst, 23 | ivec2(u_info.dst_offset.x + thread_id.x, thread_id.y), 24 | u_info.clear_value); 25 | } 26 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_clear_image1darr_u.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 64, 5 | local_size_y = 1, 6 | local_size_z = 1) in; 7 | 8 | layout(binding = 0) 9 | writeonly uniform uimage1DArray dst; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | uvec4 clear_value; 14 | ivec4 dst_offset; 15 | ivec4 dst_extent; 16 | } u_info; 17 | 18 | void main() { 19 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 20 | 21 | if (thread_id.x < u_info.dst_extent.x) { 22 | imageStore(dst, 23 | ivec2(u_info.dst_offset.x + thread_id.x, thread_id.y), 24 | u_info.clear_value); 25 | } 26 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_clear_image2d_f.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 8, 5 | local_size_y = 8, 6 | local_size_z = 1) in; 7 | 8 | layout(binding = 0) 9 | writeonly uniform image2D dst; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | vec4 clear_value; 14 | ivec4 dst_offset; 15 | ivec4 dst_extent; 16 | } u_info; 17 | 18 | void main() { 19 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 20 | 21 | if (all(lessThan(thread_id.xy, u_info.dst_extent.xy))) { 22 | imageStore(dst, 23 | u_info.dst_offset.xy + thread_id.xy, 24 | u_info.clear_value); 25 | } 26 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_clear_image2d_u.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 8, 5 | local_size_y = 8, 6 | local_size_z = 1) in; 7 | 8 | layout(binding = 0) 9 | writeonly uniform uimage2D dst; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | uvec4 clear_value; 14 | ivec4 dst_offset; 15 | ivec4 dst_extent; 16 | } u_info; 17 | 18 | void main() { 19 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 20 | 21 | if (all(lessThan(thread_id.xy, u_info.dst_extent.xy))) { 22 | imageStore(dst, 23 | u_info.dst_offset.xy + thread_id.xy, 24 | u_info.clear_value); 25 | } 26 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_clear_image2darr_f.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 8, 5 | local_size_y = 8, 6 | local_size_z = 1) in; 7 | 8 | layout(binding = 0) 9 | writeonly uniform image2DArray dst; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | vec4 clear_value; 14 | ivec4 dst_offset; 15 | ivec4 dst_extent; 16 | } u_info; 17 | 18 | void main() { 19 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 20 | 21 | if (all(lessThan(thread_id.xy, u_info.dst_extent.xy))) { 22 | imageStore(dst, 23 | ivec3(u_info.dst_offset.xy + thread_id.xy, thread_id.z), 24 | u_info.clear_value); 25 | } 26 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_clear_image2darr_u.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 8, 5 | local_size_y = 8, 6 | local_size_z = 1) in; 7 | 8 | layout(binding = 0) 9 | writeonly uniform uimage2DArray dst; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | uvec4 clear_value; 14 | ivec4 dst_offset; 15 | ivec4 dst_extent; 16 | } u_info; 17 | 18 | void main() { 19 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 20 | 21 | if (all(lessThan(thread_id.xy, u_info.dst_extent.xy))) { 22 | imageStore(dst, 23 | ivec3(u_info.dst_offset.xy + thread_id.xy, thread_id.z), 24 | u_info.clear_value); 25 | } 26 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_clear_image3d_f.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 4, 5 | local_size_y = 4, 6 | local_size_z = 4) in; 7 | 8 | layout(binding = 0) 9 | writeonly uniform image3D dst; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | vec4 clear_value; 14 | ivec4 dst_offset; 15 | ivec4 dst_extent; 16 | } u_info; 17 | 18 | void main() { 19 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 20 | 21 | if (all(lessThan(thread_id.xyz, u_info.dst_extent.xyz))) { 22 | imageStore(dst, 23 | u_info.dst_offset.xyz + thread_id.xyz, 24 | u_info.clear_value); 25 | } 26 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_clear_image3d_u.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 4, 5 | local_size_y = 4, 6 | local_size_z = 4) in; 7 | 8 | layout(binding = 0) 9 | writeonly uniform uimage3D dst; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | uvec4 clear_value; 14 | ivec4 dst_offset; 15 | ivec4 dst_extent; 16 | } u_info; 17 | 18 | void main() { 19 | ivec3 thread_id = ivec3(gl_GlobalInvocationID); 20 | 21 | if (all(lessThan(thread_id.xyz, u_info.dst_extent.xyz))) { 22 | imageStore(dst, 23 | u_info.dst_offset.xyz + thread_id.xyz, 24 | u_info.clear_value); 25 | } 26 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_copy_buffer_image.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 8, 5 | local_size_y = 8, 6 | local_size_z = 1) in; 7 | 8 | layout(binding = 0) writeonly uniform uimageBuffer u_dst; 9 | layout(binding = 1) uniform usamplerBuffer u_src; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | uvec3 dst_offset; 14 | uvec3 src_offset; 15 | uvec3 extent; 16 | uvec2 dst_size; 17 | uvec2 src_size; 18 | } u_info; 19 | 20 | void main() { 21 | if (all(lessThan(gl_GlobalInvocationID, u_info.extent))) { 22 | uvec3 dst_coord = u_info.dst_offset + gl_GlobalInvocationID; 23 | uvec3 src_coord = u_info.src_offset + gl_GlobalInvocationID; 24 | 25 | uint dst_index = dst_coord.x + u_info.dst_size.x * (dst_coord.y + u_info.dst_size.y * dst_coord.z); 26 | uint src_index = src_coord.x + u_info.src_size.x * (src_coord.y + u_info.src_size.y * src_coord.z); 27 | 28 | imageStore(u_dst, int(dst_index), texelFetch(u_src, int(src_index))); 29 | } 30 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_copy_color_1d.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(set = 0, binding = 0) 4 | uniform sampler1DArray s_image; 5 | 6 | layout(location = 0) out vec4 o_color; 7 | 8 | layout(push_constant) 9 | uniform u_info_t { 10 | ivec2 offset; 11 | } u_info; 12 | 13 | void main() { 14 | o_color = texelFetch(s_image, 15 | ivec2(gl_FragCoord.x + u_info.offset.x, gl_Layer), 0); 16 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_copy_color_2d.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(set = 0, binding = 0) 4 | uniform sampler2DArray s_image; 5 | 6 | layout(location = 0) out vec4 o_color; 7 | 8 | layout(push_constant) 9 | uniform u_info_t { 10 | ivec2 offset; 11 | } u_info; 12 | 13 | void main() { 14 | o_color = texelFetch(s_image, 15 | ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer), 0); 16 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_copy_color_ms.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(set = 0, binding = 0) 4 | uniform sampler2DMSArray s_image; 5 | 6 | layout(location = 0) out vec4 o_color; 7 | 8 | layout(push_constant) 9 | uniform u_info_t { 10 | ivec2 offset; 11 | } u_info; 12 | 13 | void main() { 14 | o_color = texelFetch(s_image, 15 | ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer), 16 | gl_SampleID); 17 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_copy_depth_1d.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(set = 0, binding = 0) 4 | uniform sampler1DArray s_image; 5 | 6 | layout(push_constant) 7 | uniform u_info_t { 8 | ivec2 offset; 9 | } u_info; 10 | 11 | void main() { 12 | gl_FragDepth = texelFetch(s_image, 13 | ivec2(gl_FragCoord.x + u_info.offset.x, gl_Layer), 0).r; 14 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_copy_depth_2d.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(set = 0, binding = 0) 4 | uniform sampler2DArray s_image; 5 | 6 | layout(push_constant) 7 | uniform u_info_t { 8 | ivec2 offset; 9 | } u_info; 10 | 11 | void main() { 12 | gl_FragDepth = texelFetch(s_image, 13 | ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer), 0).r; 14 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_copy_depth_ms.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(set = 0, binding = 0) 4 | uniform sampler2DMSArray s_image; 5 | 6 | layout(push_constant) 7 | uniform u_info_t { 8 | ivec2 offset; 9 | } u_info; 10 | 11 | void main() { 12 | gl_FragDepth = texelFetch(s_image, 13 | ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer), 14 | gl_SampleID).r; 15 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_copy_depth_stencil_1d.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_ARB_shader_stencil_export : enable 4 | 5 | layout(set = 0, binding = 0) 6 | uniform sampler1DArray s_depth; 7 | 8 | layout(set = 0, binding = 1) 9 | uniform usampler1DArray s_stencil; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | ivec2 offset; 14 | } u_info; 15 | 16 | void main() { 17 | ivec2 coord = ivec2(gl_FragCoord.x + u_info.offset.x, gl_Layer); 18 | gl_FragDepth = texelFetch(s_depth, coord, 0).r; 19 | gl_FragStencilRefARB = int(texelFetch(s_stencil, coord, 0).r); 20 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_copy_depth_stencil_2d.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_ARB_shader_stencil_export : enable 4 | 5 | layout(set = 0, binding = 0) 6 | uniform sampler2DArray s_depth; 7 | 8 | layout(set = 0, binding = 1) 9 | uniform usampler2DArray s_stencil; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | ivec2 offset; 14 | } u_info; 15 | 16 | void main() { 17 | ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset.xy, gl_Layer); 18 | gl_FragDepth = texelFetch(s_depth, coord, 0).r; 19 | gl_FragStencilRefARB = int(texelFetch(s_stencil, coord, 0).r); 20 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_copy_depth_stencil_ms.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_ARB_shader_stencil_export : enable 4 | 5 | layout(set = 0, binding = 0) 6 | uniform sampler2DMSArray s_depth; 7 | 8 | layout(set = 0, binding = 1) 9 | uniform usampler2DMSArray s_stencil; 10 | 11 | layout(push_constant) 12 | uniform u_info_t { 13 | ivec2 offset; 14 | } u_info; 15 | 16 | void main() { 17 | ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset.xy, gl_Layer); 18 | gl_FragDepth = texelFetch(s_depth, coord, gl_SampleID).r; 19 | gl_FragStencilRefARB = int(texelFetch(s_stencil, coord, gl_SampleID).r); 20 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_fullscreen_geom.geom: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(triangles) in; 4 | layout(triangle_strip, max_vertices = 3) out; 5 | 6 | layout(location = 0) in int i_instance[3]; 7 | layout(location = 1) in vec2 i_texcoord[3]; 8 | layout(location = 0) out vec2 o_texcoord; 9 | 10 | void main() { 11 | for (int i = 0; i < 3; i++) { 12 | o_texcoord = i_texcoord[i]; 13 | gl_Layer = i_instance[i]; 14 | gl_Position = gl_in[i].gl_Position; 15 | EmitVertex(); 16 | } 17 | 18 | EndPrimitive(); 19 | } 20 | -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_fullscreen_layer_vert.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_ARB_shader_viewport_layer_array : enable 4 | 5 | layout(location = 0) out vec2 o_texcoord; 6 | 7 | void main() { 8 | vec2 coord = vec2( 9 | float(gl_VertexIndex & 2), 10 | float(gl_VertexIndex & 1) * 2.0f); 11 | 12 | o_texcoord = coord; 13 | gl_Layer = gl_InstanceIndex; 14 | gl_Position = vec4(-1.0f + 2.0f * coord, 0.0f, 1.0f); 15 | } 16 | -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_fullscreen_vert.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) out int o_instance; 4 | layout(location = 1) out vec2 o_texcoord; 5 | 6 | void main() { 7 | vec2 coord = vec2( 8 | float(gl_VertexIndex & 2), 9 | float(gl_VertexIndex & 1) * 2.0f); 10 | 11 | o_instance = gl_InstanceIndex; 12 | o_texcoord = coord; 13 | gl_Position = vec4(-1.0f + 2.0f * coord, 0.0f, 1.0f); 14 | } 15 | -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_pack_d24s8.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 8, 5 | local_size_y = 8, 6 | local_size_z = 1) in; 7 | 8 | layout(binding = 0, std430) 9 | writeonly buffer s_buffer_t { 10 | uint data[]; 11 | } s_buffer; 12 | 13 | layout(binding = 1) uniform sampler2DArray u_depth; 14 | layout(binding = 2) uniform usampler2DArray u_stencil; 15 | 16 | layout(push_constant) 17 | uniform u_info_t { 18 | uvec2 src_offset; 19 | uvec2 src_extent; 20 | uvec2 dst_offset; 21 | uvec2 dst_extent; 22 | } u_info; 23 | 24 | void main() { 25 | if (all(lessThan(gl_GlobalInvocationID.xy, u_info.src_extent))) { 26 | uvec3 src_coord = uvec3( 27 | gl_GlobalInvocationID.xy + u_info.src_offset, 28 | gl_GlobalInvocationID.z); 29 | 30 | uvec3 dst_coord = uvec3( 31 | gl_GlobalInvocationID.xy + u_info.dst_offset, 32 | gl_GlobalInvocationID.z); 33 | 34 | uint dst_index = dst_coord.x + u_info.dst_extent.x * (dst_coord.y + u_info.dst_extent.y * dst_coord.z); 35 | 36 | float depth = texelFetch(u_depth, ivec3(src_coord), 0).r; 37 | uint stencil = texelFetch(u_stencil, ivec3(src_coord), 0).r; 38 | 39 | s_buffer.data[dst_index] = uint(mix(0.0f, float((1 << 24) - 1), depth)) | (stencil << 24); 40 | } 41 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_pack_d32s8.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 8, 5 | local_size_y = 8, 6 | local_size_z = 1) in; 7 | 8 | struct d32s8_t { 9 | float d32; 10 | uint s8; 11 | }; 12 | 13 | layout(binding = 0, std430) 14 | writeonly buffer s_buffer_t { 15 | d32s8_t data[]; 16 | } s_buffer; 17 | 18 | layout(binding = 1) uniform sampler2DArray u_depth; 19 | layout(binding = 2) uniform usampler2DArray u_stencil; 20 | 21 | layout(push_constant) 22 | uniform u_info_t { 23 | uvec2 src_offset; 24 | uvec2 src_extent; 25 | uvec2 dst_offset; 26 | uvec2 dst_extent; 27 | } u_info; 28 | 29 | void main() { 30 | if (all(lessThan(gl_GlobalInvocationID.xy, u_info.src_extent))) { 31 | uvec3 src_coord = uvec3( 32 | gl_GlobalInvocationID.xy + u_info.src_offset, 33 | gl_GlobalInvocationID.z); 34 | 35 | uvec3 dst_coord = uvec3( 36 | gl_GlobalInvocationID.xy + u_info.dst_offset, 37 | gl_GlobalInvocationID.z); 38 | 39 | uint dst_index = dst_coord.x + u_info.dst_extent.x * (dst_coord.y + u_info.dst_extent.y * dst_coord.z); 40 | 41 | s_buffer.data[dst_index].d32 = texelFetch(u_depth, ivec3(src_coord), 0).r; 42 | s_buffer.data[dst_index].s8 = texelFetch(u_stencil, ivec3(src_coord), 0).r; 43 | } 44 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_present_frag.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(constant_id = 1) const bool s_gamma_bound = true; 4 | 5 | layout(binding = 0) uniform sampler2D s_image; 6 | layout(binding = 1) uniform sampler1D s_gamma; 7 | 8 | layout(location = 0) out vec4 o_color; 9 | 10 | layout(push_constant) 11 | uniform present_info_t { 12 | ivec2 src_offset; 13 | ivec2 dst_offset; 14 | }; 15 | 16 | void main() { 17 | ivec2 coord = ivec2(gl_FragCoord.xy) + src_offset - dst_offset; 18 | o_color = texelFetch(s_image, coord, 0); 19 | 20 | if (s_gamma_bound) { 21 | o_color = vec4( 22 | texture(s_gamma, o_color.r).r, 23 | texture(s_gamma, o_color.g).g, 24 | texture(s_gamma, o_color.b).b, 25 | o_color.a); 26 | } 27 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_present_frag_blit.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(constant_id = 1) const bool s_gamma_bound = true; 4 | 5 | layout(binding = 0) uniform sampler2D s_image; 6 | layout(binding = 1) uniform sampler1D s_gamma; 7 | 8 | layout(location = 0) in vec2 i_coord; 9 | layout(location = 0) out vec4 o_color; 10 | 11 | layout(push_constant) 12 | uniform present_info_t { 13 | ivec2 src_offset; 14 | uvec2 src_extent; 15 | }; 16 | 17 | void main() { 18 | vec2 coord = vec2(src_offset) + vec2(src_extent) * i_coord; 19 | o_color = textureLod(s_image, coord, 0.0f); 20 | 21 | if (s_gamma_bound) { 22 | o_color = vec4( 23 | texture(s_gamma, o_color.r).r, 24 | texture(s_gamma, o_color.g).g, 25 | texture(s_gamma, o_color.b).b, 26 | o_color.a); 27 | } 28 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_present_frag_ms.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(constant_id = 1) const bool s_gamma_bound = true; 4 | layout(constant_id = 1225) const uint c_samples = 0; 5 | 6 | layout(binding = 0) uniform sampler2DMS s_image; 7 | layout(binding = 1) uniform sampler1D s_gamma; 8 | 9 | layout(location = 0) out vec4 o_color; 10 | 11 | layout(push_constant) 12 | uniform present_info_t { 13 | ivec2 src_offset; 14 | ivec2 dst_offset; 15 | }; 16 | 17 | void main() { 18 | ivec2 coord = ivec2(gl_FragCoord.xy) + src_offset - dst_offset; 19 | o_color = texelFetch(s_image, coord, 0); 20 | 21 | for (uint i = 1; i < c_samples; i++) 22 | o_color += texelFetch(s_image, coord, int(i)); 23 | 24 | o_color /= float(c_samples); 25 | 26 | if (s_gamma_bound) { 27 | o_color = vec4( 28 | texture(s_gamma, o_color.r).r, 29 | texture(s_gamma, o_color.g).g, 30 | texture(s_gamma, o_color.b).b, 31 | o_color.a); 32 | } 33 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_present_frag_ms_amd.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_AMD_shader_fragment_mask: enable 4 | 5 | layout(constant_id = 1) const bool s_gamma_bound = true; 6 | layout(constant_id = 1225) const uint c_samples = 0; 7 | 8 | layout(binding = 0) uniform sampler2DMS s_image; 9 | layout(binding = 1) uniform sampler1D s_gamma; 10 | 11 | layout(location = 0) out vec4 o_color; 12 | 13 | layout(push_constant) 14 | uniform present_info_t { 15 | ivec2 src_offset; 16 | ivec2 dst_offset; 17 | }; 18 | 19 | void main() { 20 | ivec2 coord = ivec2(gl_FragCoord.xy) + src_offset - dst_offset; 21 | 22 | // check dxvk_resolve_frag_f_amd.frag for documentation 23 | uint fragMask = fragmentMaskFetchAMD(s_image, coord); 24 | uint fragCount = 0u; 25 | 26 | for (int i = 0; i < 4 * c_samples; i += 4) { 27 | uint fragIndex = bitfieldExtract(fragMask, i, 4); 28 | fragCount += 1u << (fragIndex << 2); 29 | } 30 | 31 | o_color = vec4(0.0f); 32 | 33 | while (fragCount != 0) { 34 | int fragIndex = findLSB(fragCount) >> 2; 35 | int fragShift = fragIndex << 2; 36 | 37 | o_color += fragmentFetchAMD(s_image, coord, fragIndex) 38 | * float(bitfieldExtract(fragCount, fragShift, 4)); 39 | 40 | fragCount = bitfieldInsert(fragCount, 0, fragShift, 4); 41 | } 42 | 43 | o_color /= float(c_samples); 44 | 45 | if (s_gamma_bound) { 46 | o_color = vec4( 47 | texture(s_gamma, o_color.r).r, 48 | texture(s_gamma, o_color.g).g, 49 | texture(s_gamma, o_color.b).b, 50 | o_color.a); 51 | } 52 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_present_vert.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) out vec2 o_coord; 4 | 5 | void main() { 6 | vec2 coord = vec2( 7 | float(gl_VertexIndex & 2), 8 | float(gl_VertexIndex & 1) * 2.0f); 9 | 10 | o_coord = coord; 11 | gl_Position = vec4(-1.0f + 2.0f * coord, 0.0f, 1.0f); 12 | } 13 | -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_resolve_frag_f.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(constant_id = 0) const int c_samples = 1; 4 | 5 | layout(binding = 0) uniform sampler2DMSArray s_image; 6 | 7 | layout(location = 0) out vec4 o_color; 8 | 9 | layout(push_constant) 10 | uniform u_info_t { 11 | ivec2 offset; 12 | } u_info; 13 | 14 | void main() { 15 | ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer); 16 | vec4 color = vec4(0.0f); 17 | for (int i = 0; i < c_samples; i++) 18 | color += texelFetch(s_image, coord, i); 19 | o_color = color / float(c_samples); 20 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_resolve_frag_f_amd.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | #extension GL_AMD_shader_fragment_mask: enable 4 | 5 | layout(constant_id = 0) const int c_samples = 1; 6 | 7 | layout(set = 0, binding = 0) 8 | uniform sampler2DMSArray s_image; 9 | 10 | layout(location = 0) out vec4 o_color; 11 | 12 | layout(push_constant) 13 | uniform u_info_t { 14 | ivec2 offset; 15 | } u_info; 16 | 17 | void main() { 18 | ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer); 19 | 20 | // get a four-bit fragment index for each sample 21 | uint fragMask = fragmentMaskFetchAMD(s_image, coord); 22 | 23 | // count number of occurences of each fragment 24 | // index in one four-bit counter for each sample 25 | uint fragCount = 0u; 26 | 27 | for (int i = 0; i < 4 * c_samples; i += 4) { 28 | uint fragIndex = bitfieldExtract(fragMask, i, 4); 29 | fragCount += 1u << (fragIndex << 2); 30 | } 31 | 32 | // perform necessary texture lookups to compute 33 | // final fragment color 34 | o_color = vec4(0.0f); 35 | 36 | while (fragCount != 0) { 37 | int fragIndex = findLSB(fragCount) >> 2; 38 | int fragShift = fragIndex << 2; 39 | 40 | o_color += fragmentFetchAMD(s_image, coord, fragIndex) 41 | * float(bitfieldExtract(fragCount, fragShift, 4)); 42 | 43 | fragCount = bitfieldInsert(fragCount, 0, fragShift, 4); 44 | } 45 | 46 | o_color /= float(c_samples); 47 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_resolve_frag_i.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(binding = 0) uniform isampler2DMSArray s_image; 4 | 5 | layout(location = 0) out ivec4 o_color; 6 | 7 | layout(push_constant) 8 | uniform u_info_t { 9 | ivec2 offset; 10 | } u_info; 11 | 12 | void main() { 13 | ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer); 14 | o_color = texelFetch(s_image, coord, 0); 15 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_resolve_frag_u.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(binding = 0) uniform usampler2DMSArray s_image; 4 | 5 | layout(location = 0) out uvec4 o_color; 6 | 7 | layout(push_constant) 8 | uniform u_info_t { 9 | ivec2 offset; 10 | } u_info; 11 | 12 | void main() { 13 | ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer); 14 | o_color = texelFetch(s_image, coord, 0); 15 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_unpack_d24s8.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 64, 5 | local_size_y = 1, 6 | local_size_z = 1) in; 7 | 8 | layout(binding = 0, r32ui) writeonly uniform uimageBuffer u_depth; 9 | layout(binding = 1, r8ui) writeonly uniform uimageBuffer u_stencil; 10 | 11 | layout(binding = 2) 12 | readonly buffer s_buffer_t { 13 | uint data[]; 14 | } s_buffer; 15 | 16 | layout(push_constant) 17 | uniform u_info_t { 18 | uvec2 src_offset; 19 | uvec2 src_extent; 20 | uvec2 dst_offset; 21 | uvec2 dst_extent; 22 | } u_info; 23 | 24 | void main() { 25 | if (all(lessThan(gl_GlobalInvocationID.xy, u_info.dst_extent))) { 26 | uvec3 src_coord = uvec3( 27 | gl_GlobalInvocationID.xy + u_info.src_offset, 28 | gl_GlobalInvocationID.z); 29 | 30 | uvec3 dst_coord = uvec3( 31 | gl_GlobalInvocationID.xy + u_info.dst_offset, 32 | gl_GlobalInvocationID.z); 33 | 34 | uint src_index = src_coord.x + u_info.src_extent.x * (src_coord.y + u_info.src_extent.y * src_coord.z); 35 | uint dst_index = dst_coord.x + u_info.dst_extent.x * (dst_coord.y + u_info.dst_extent.y * dst_coord.z); 36 | 37 | uint src_data = s_buffer.data[src_index]; 38 | imageStore(u_depth, int(dst_index), uvec4(src_data & 0xFFFFFF)); 39 | imageStore(u_stencil, int(dst_index), uvec4(src_data >> 24)); 40 | } 41 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_unpack_d24s8_as_d32s8.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 64, 5 | local_size_y = 1, 6 | local_size_z = 1) in; 7 | 8 | layout(binding = 0, r32f) writeonly uniform imageBuffer u_depth; 9 | layout(binding = 1, r8ui) writeonly uniform uimageBuffer u_stencil; 10 | 11 | layout(binding = 2) 12 | readonly buffer s_buffer_t { 13 | uint data[]; 14 | } s_buffer; 15 | 16 | layout(push_constant) 17 | uniform u_info_t { 18 | uvec2 src_offset; 19 | uvec2 src_extent; 20 | uvec2 dst_offset; 21 | uvec2 dst_extent; 22 | } u_info; 23 | 24 | void main() { 25 | if (all(lessThan(gl_GlobalInvocationID.xy, u_info.dst_extent))) { 26 | uvec3 src_coord = uvec3( 27 | gl_GlobalInvocationID.xy + u_info.src_offset, 28 | gl_GlobalInvocationID.z); 29 | 30 | uvec3 dst_coord = uvec3( 31 | gl_GlobalInvocationID.xy + u_info.dst_offset, 32 | gl_GlobalInvocationID.z); 33 | 34 | uint src_index = src_coord.x + u_info.src_extent.x * (src_coord.y + u_info.src_extent.y * src_coord.z); 35 | uint dst_index = dst_coord.x + u_info.dst_extent.x * (dst_coord.y + u_info.dst_extent.y * dst_coord.z); 36 | 37 | uint src_data = s_buffer.data[src_index]; 38 | imageStore(u_depth, int(dst_index), vec4(float(src_data & 0xFFFFFF) / float(0xFFFFFF))); 39 | imageStore(u_stencil, int(dst_index), uvec4(src_data >> 24)); 40 | } 41 | } -------------------------------------------------------------------------------- /src/dxvk/shaders/dxvk_unpack_d32s8.comp: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout( 4 | local_size_x = 64, 5 | local_size_y = 1, 6 | local_size_z = 1) in; 7 | 8 | struct d32s8_t { 9 | float d32; 10 | uint s8; 11 | }; 12 | 13 | layout(binding = 0, r32f) writeonly uniform imageBuffer u_depth; 14 | layout(binding = 1, r8ui) writeonly uniform uimageBuffer u_stencil; 15 | 16 | layout(binding = 2) 17 | readonly buffer s_buffer_t { 18 | d32s8_t data[]; 19 | } s_buffer; 20 | 21 | layout(push_constant) 22 | uniform u_info_t { 23 | uvec2 src_offset; 24 | uvec2 src_extent; 25 | uvec2 dst_offset; 26 | uvec2 dst_extent; 27 | } u_info; 28 | 29 | void main() { 30 | if (all(lessThan(gl_GlobalInvocationID.xy, u_info.dst_extent))) { 31 | uvec3 src_coord = uvec3( 32 | gl_GlobalInvocationID.xy + u_info.src_offset, 33 | gl_GlobalInvocationID.z); 34 | 35 | uvec3 dst_coord = uvec3( 36 | gl_GlobalInvocationID.xy + u_info.dst_offset, 37 | gl_GlobalInvocationID.z); 38 | 39 | uint src_index = src_coord.x + u_info.src_extent.x * (src_coord.y + u_info.src_extent.y * src_coord.z); 40 | uint dst_index = dst_coord.x + u_info.dst_extent.x * (dst_coord.y + u_info.dst_extent.y * dst_coord.z); 41 | 42 | d32s8_t src_data = s_buffer.data[src_index]; 43 | imageStore(u_depth, int(dst_index), vec4(src_data.d32)); 44 | imageStore(u_stencil, int(dst_index), uvec4(src_data.s8)); 45 | } 46 | } -------------------------------------------------------------------------------- /src/dxvk_config/dxvk_config.cpp: -------------------------------------------------------------------------------- 1 | #include "../dxgi/dxgi_include.h" 2 | 3 | #include "../util/config/config.h" 4 | 5 | #include "dxvk_config.h" 6 | 7 | namespace dxvk { 8 | Logger Logger::s_instance("dxvk_config.log"); 9 | } 10 | 11 | static int32_t parsePciId(const std::string& str) { 12 | if (str.size() != 4) 13 | return -1; 14 | 15 | int32_t id = 0; 16 | 17 | for (size_t i = 0; i < str.size(); i++) { 18 | id *= 16; 19 | 20 | if (str[i] >= '0' && str[i] <= '9') 21 | id += str[i] - '0'; 22 | else if (str[i] >= 'A' && str[i] <= 'F') 23 | id += str[i] - 'A' + 10; 24 | else if (str[i] >= 'a' && str[i] <= 'f') 25 | id += str[i] - 'a' + 10; 26 | else 27 | return -1; 28 | } 29 | 30 | return id; 31 | } 32 | 33 | extern "C" { 34 | using namespace dxvk; 35 | 36 | DLLEXPORT HRESULT __stdcall DXVKGetOptions(struct DXVKOptions *opts) 37 | { 38 | Config config(Config::getUserConfig()); 39 | 40 | config.merge(Config::getAppConfig(env::getExePath())); 41 | 42 | opts->nvapiHack = config.getOption("dxgi.nvapiHack", true) ? 1 : 0; 43 | opts->customVendorId = parsePciId(config.getOption("dxgi.customVendorId")); 44 | opts->customDeviceId = parsePciId(config.getOption("dxgi.customDeviceId")); 45 | 46 | return S_OK; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/dxvk_config/dxvk_config.def: -------------------------------------------------------------------------------- 1 | LIBRARY DXVK_CONFIG.DLL 2 | EXPORTS 3 | DXVKGetOptions 4 | -------------------------------------------------------------------------------- /src/dxvk_config/dxvk_config.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | 5 | struct DXVKOptions { 6 | int32_t customVendorId; 7 | int32_t customDeviceId; 8 | int32_t nvapiHack; 9 | }; 10 | 11 | DLLEXPORT HRESULT __stdcall DXVKGetOptions(struct DXVKOptions *out_opts); 12 | 13 | #ifdef __cplusplus 14 | } 15 | #endif 16 | -------------------------------------------------------------------------------- /src/dxvk_config/dxvk_config.spec: -------------------------------------------------------------------------------- 1 | @ stdcall DXVKGetOptions(ptr) 2 | -------------------------------------------------------------------------------- /src/dxvk_config/meson.build: -------------------------------------------------------------------------------- 1 | dxvk_config_res = wrc_generator.process('version.rc') 2 | 3 | dxvk_config_src = [ 4 | 'dxvk_config.cpp', 5 | ] 6 | 7 | dxvk_config_dll = shared_library('dxvk_config'+dll_ext, dxvk_config_src, dxvk_config_res, 8 | name_prefix : '', 9 | dependencies : [ lib_dxgi, dxvk_dep ], 10 | include_directories : dxvk_include_path, 11 | install : true, 12 | objects : not dxvk_is_msvc ? 'dxvk_config'+def_spec_ext : [], 13 | vs_module_defs : 'dxvk_config'+def_spec_ext, 14 | override_options : ['cpp_std='+dxvk_cpp_std]) 15 | 16 | install_headers('dxvk_config.h', 17 | subdir : 'dxvk') 18 | 19 | dxvk_config_dep = declare_dependency( 20 | link_with : [ dxvk_config_dll ], 21 | include_directories : [ dxvk_include_path ]) 22 | -------------------------------------------------------------------------------- /src/dxvk_config/version.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // DLL version information. 4 | VS_VERSION_INFO VERSIONINFO 5 | FILEVERSION 10,0,17763,1 6 | PRODUCTVERSION 10,0,17763,1 7 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 8 | FILEFLAGS 0 9 | FILEOS VOS_NT_WINDOWS32 10 | FILETYPE VFT_DLL 11 | FILESUBTYPE VFT2_UNKNOWN 12 | BEGIN 13 | BLOCK "StringFileInfo" 14 | BEGIN 15 | BLOCK "080904b0" 16 | BEGIN 17 | VALUE "CompanyName", "DXVK" 18 | VALUE "FileDescription", "DXVK Config" 19 | VALUE "FileVersion", "10.0.17763.1 (WinBuild.160101.0800)" 20 | VALUE "InternalName", "DXVK_CONFIG.dll" 21 | VALUE "LegalCopyright", "zlib/libpng license" 22 | VALUE "OriginalFilename", "DXVK_CONFIG.dll" 23 | VALUE "ProductName", "DXVK" 24 | VALUE "ProductVersion", "10.0.17763.1" 25 | END 26 | END 27 | BLOCK "VarFileInfo" 28 | BEGIN 29 | VALUE "Translation", 0x0809, 1200 30 | END 31 | END 32 | 33 | -------------------------------------------------------------------------------- /src/meson.build: -------------------------------------------------------------------------------- 1 | subdir('util') 2 | subdir('spirv') 3 | subdir('vulkan') 4 | subdir('dxvk') 5 | subdir('dxvk_config') 6 | 7 | if get_option('enable_dxgi') 8 | if not get_option('enable_d3d11') 9 | error('D3D11 is required for DXGI.') 10 | endif 11 | subdir('dxgi') 12 | endif 13 | 14 | if get_option('enable_d3d10') or get_option('enable_d3d11') or get_option('enable_tests') 15 | subdir('dxbc') 16 | endif 17 | 18 | if get_option('enable_d3d11') 19 | subdir('d3d11') 20 | endif 21 | 22 | if get_option('enable_d3d10') 23 | if not get_option('enable_d3d11') 24 | error('D3D11 is required for D3D10.') 25 | endif 26 | subdir('d3d10') 27 | endif 28 | 29 | if get_option('enable_d3d9') 30 | subdir('dxso') 31 | subdir('d3d9') 32 | endif 33 | 34 | # Nothing selected 35 | if not get_option('enable_d3d9') and not get_option('enable_d3d10') and not get_option('enable_d3d11') and not get_option('enable_tests') 36 | warning('Nothing selected to be built. Are you missing a frontend or tests?') 37 | endif 38 | -------------------------------------------------------------------------------- /src/spirv/meson.build: -------------------------------------------------------------------------------- 1 | spirv_src = files([ 2 | 'spirv_code_buffer.cpp', 3 | 'spirv_compression.cpp', 4 | 'spirv_module.cpp', 5 | ]) 6 | 7 | spirv_lib = static_library('spirv', spirv_src, 8 | include_directories : [ dxvk_include_path ], 9 | override_options : ['cpp_std='+dxvk_cpp_std]) 10 | -------------------------------------------------------------------------------- /src/spirv/spirv_compression.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "spirv_code_buffer.h" 6 | 7 | namespace dxvk { 8 | 9 | /** 10 | * \brief Compressed SPIR-V code buffer 11 | * 12 | * Implements a fast in-memory compression 13 | * to keep memory footprint low. 14 | */ 15 | class SpirvCompressedBuffer { 16 | constexpr static uint32_t NumMaskWords = 32; 17 | public: 18 | 19 | SpirvCompressedBuffer(); 20 | 21 | SpirvCompressedBuffer( 22 | const SpirvCodeBuffer& code); 23 | 24 | ~SpirvCompressedBuffer(); 25 | 26 | SpirvCodeBuffer decompress() const; 27 | 28 | private: 29 | 30 | uint32_t m_size; 31 | std::vector m_mask; 32 | std::vector m_code; 33 | 34 | }; 35 | 36 | } -------------------------------------------------------------------------------- /src/spirv/spirv_include.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../util/log/log.h" 4 | #include "../util/log/log_debug.h" 5 | 6 | #include "../util/util_error.h" 7 | #include "../util/util_flags.h" 8 | #include "../util/util_likely.h" 9 | #include "../util/util_string.h" 10 | 11 | #include "../util/rc/util_rc.h" 12 | #include "../util/rc/util_rc_ptr.h" 13 | -------------------------------------------------------------------------------- /src/util/com/com_guid.cpp: -------------------------------------------------------------------------------- 1 | #include "com_guid.h" 2 | 3 | #include "../../d3d11/d3d11_interfaces.h" 4 | 5 | #include "../../dxgi/dxgi_interfaces.h" 6 | 7 | std::ostream& operator << (std::ostream& os, REFIID guid) { 8 | os << std::hex << std::setfill('0') 9 | << std::setw(8) << guid.Data1 << '-'; 10 | 11 | os << std::hex << std::setfill('0') 12 | << std::setw(4) << guid.Data2 << '-'; 13 | 14 | os << std::hex << std::setfill('0') 15 | << std::setw(4) << guid.Data3 << '-'; 16 | 17 | os << std::hex << std::setfill('0') 18 | << std::setw(2) << static_cast(guid.Data4[0]) 19 | << std::setw(2) << static_cast(guid.Data4[1]) 20 | << '-' 21 | << std::setw(2) << static_cast(guid.Data4[2]) 22 | << std::setw(2) << static_cast(guid.Data4[3]) 23 | << std::setw(2) << static_cast(guid.Data4[4]) 24 | << std::setw(2) << static_cast(guid.Data4[5]) 25 | << std::setw(2) << static_cast(guid.Data4[6]) 26 | << std::setw(2) << static_cast(guid.Data4[7]); 27 | return os; 28 | } 29 | -------------------------------------------------------------------------------- /src/util/com/com_guid.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "com_include.h" 7 | 8 | std::ostream& operator << (std::ostream& os, REFIID guid); 9 | -------------------------------------------------------------------------------- /src/util/com/com_include.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // GCC complains about the COM interfaces 4 | // not having virtual destructors 5 | #ifdef __GNUC__ 6 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 7 | #endif // __GNUC__ 8 | 9 | #define WIN32_LEAN_AND_MEAN 10 | #include 11 | #include 12 | 13 | // GCC: -std options disable certain keywords 14 | // https://gcc.gnu.org/onlinedocs/gcc/Alternate-Keywords.html 15 | #if defined(__WINE__) && !defined(typeof) 16 | #define typeof __typeof 17 | #endif 18 | -------------------------------------------------------------------------------- /src/util/log/log.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../thread.h" 9 | 10 | namespace dxvk { 11 | 12 | enum class LogLevel : uint32_t { 13 | Trace = 0, 14 | Debug = 1, 15 | Info = 2, 16 | Warn = 3, 17 | Error = 4, 18 | None = 5, 19 | }; 20 | 21 | /** 22 | * \brief Logger 23 | * 24 | * Logger for one DLL. Creates a text file and 25 | * writes all log messages to that file. 26 | */ 27 | class Logger { 28 | 29 | public: 30 | 31 | Logger(const std::string& file_name); 32 | ~Logger(); 33 | 34 | static void trace(const std::string& message); 35 | static void debug(const std::string& message); 36 | static void info (const std::string& message); 37 | static void warn (const std::string& message); 38 | static void err (const std::string& message); 39 | static void log (LogLevel level, const std::string& message); 40 | 41 | static LogLevel logLevel() { 42 | return s_instance.m_minLevel; 43 | } 44 | 45 | private: 46 | 47 | static Logger s_instance; 48 | 49 | const LogLevel m_minLevel; 50 | 51 | dxvk::mutex m_mutex; 52 | std::ofstream m_fileStream; 53 | 54 | void emitMsg(LogLevel level, const std::string& message); 55 | 56 | static LogLevel getMinLogLevel(); 57 | 58 | static std::string getFileName( 59 | const std::string& base); 60 | 61 | }; 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/util/log/log_debug.cpp: -------------------------------------------------------------------------------- 1 | #include "log_debug.h" 2 | 3 | namespace dxvk::debug { 4 | 5 | std::string methodName(const std::string& prettyName) { 6 | size_t end = prettyName.find("("); 7 | size_t begin = prettyName.substr(0, end).rfind(" ") + 1; 8 | return prettyName.substr(begin,end - begin); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/util/log/log_debug.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "log.h" 6 | 7 | #ifdef _MSC_VER 8 | #define METHOD_NAME __FUNCSIG__ 9 | #else 10 | #define METHOD_NAME __PRETTY_FUNCTION__ 11 | #endif 12 | 13 | #define TRACE_ENABLED 14 | 15 | #ifdef TRACE_ENABLED 16 | #define TRACE(...) \ 17 | do { dxvk::debug::trace(METHOD_NAME, ##__VA_ARGS__); } while (0) 18 | #else 19 | #define TRACE(...) \ 20 | do { } while (0) 21 | #endif 22 | 23 | namespace dxvk::debug { 24 | 25 | std::string methodName(const std::string& prettyName); 26 | 27 | inline void traceArgs(std::stringstream& stream) { } 28 | 29 | template 30 | void traceArgs(std::stringstream& stream, const Arg1& arg1) { 31 | stream << arg1; 32 | } 33 | 34 | template 35 | void traceArgs(std::stringstream& stream, const Arg1& arg1, const Arg2& arg2, const Args&... args) { 36 | stream << arg1 << ","; 37 | traceArgs(stream, arg2, args...); 38 | } 39 | 40 | template 41 | void trace(const std::string& funcName, const Args&... args) { 42 | std::stringstream stream; 43 | stream << methodName(funcName) << "("; 44 | traceArgs(stream, args...); 45 | stream << ")"; 46 | Logger::trace(stream.str()); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/util/meson.build: -------------------------------------------------------------------------------- 1 | util_src = files([ 2 | 'util_env.cpp', 3 | 'util_string.cpp', 4 | 'util_fps_limiter.cpp', 5 | 'util_gdi.cpp', 6 | 'util_luid.cpp', 7 | 'util_matrix.cpp', 8 | 'util_monitor.cpp', 9 | 10 | 'com/com_guid.cpp', 11 | 'com/com_private_data.cpp', 12 | 13 | 'config/config.cpp', 14 | 15 | 'log/log.cpp', 16 | 'log/log_debug.cpp', 17 | 18 | 'sha1/sha1.c', 19 | 'sha1/sha1_util.cpp', 20 | 21 | 'sync/sync_recursive.cpp', 22 | ]) 23 | 24 | util_lib = static_library('util', util_src, 25 | include_directories : [ dxvk_include_path ], 26 | override_options : ['cpp_std='+dxvk_cpp_std]) 27 | 28 | util_dep = declare_dependency( 29 | link_with : [ util_lib ]) 30 | -------------------------------------------------------------------------------- /src/util/rc/util_rc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace dxvk { 6 | 7 | /** 8 | * \brief Reference-counted object 9 | */ 10 | class RcObject { 11 | 12 | public: 13 | 14 | /** 15 | * \brief Increments reference count 16 | * \returns New reference count 17 | */ 18 | uint32_t incRef() { 19 | return ++m_refCount; 20 | } 21 | 22 | /** 23 | * \brief Decrements reference count 24 | * \returns New reference count 25 | */ 26 | uint32_t decRef() { 27 | return --m_refCount; 28 | } 29 | 30 | private: 31 | 32 | std::atomic m_refCount = { 0u }; 33 | 34 | }; 35 | 36 | } -------------------------------------------------------------------------------- /src/util/sha1/sha1_util.cpp: -------------------------------------------------------------------------------- 1 | #include "sha1.h" 2 | #include "sha1_util.h" 3 | 4 | namespace dxvk { 5 | 6 | std::string Sha1Hash::toString() const { 7 | static const char nibbles[] 8 | = { '0', '1', '2', '3', '4', '5', '6', '7', 9 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 10 | 11 | std::string result; 12 | result.resize(2 * m_digest.size()); 13 | 14 | for (uint32_t i = 0; i < m_digest.size(); i++) { 15 | result.at(2 * i + 0) = nibbles[(m_digest[i] >> 4) & 0xF]; 16 | result.at(2 * i + 1) = nibbles[(m_digest[i] >> 0) & 0xF]; 17 | } 18 | 19 | return result; 20 | } 21 | 22 | 23 | Sha1Hash Sha1Hash::compute( 24 | const void* data, 25 | size_t size) { 26 | Sha1Data chunk = { data, size }; 27 | return compute(1, &chunk); 28 | } 29 | 30 | 31 | Sha1Hash Sha1Hash::compute( 32 | size_t numChunks, 33 | const Sha1Data* chunks) { 34 | Sha1Digest digest; 35 | 36 | SHA1_CTX ctx; 37 | SHA1Init(&ctx); 38 | 39 | for (size_t i = 0; i < numChunks; i++) { 40 | auto ptr = reinterpret_cast(chunks[i].data); 41 | SHA1Update(&ctx, ptr, chunks[i].size); 42 | } 43 | 44 | SHA1Final(digest.data(), &ctx); 45 | return Sha1Hash(digest); 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /src/util/sha1/sha1_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace dxvk { 8 | 9 | using Sha1Digest = std::array; 10 | 11 | struct Sha1Data { 12 | const void* data; 13 | size_t size; 14 | }; 15 | 16 | class Sha1Hash { 17 | 18 | public: 19 | 20 | Sha1Hash() { } 21 | Sha1Hash(const Sha1Digest& digest) 22 | : m_digest(digest) { } 23 | 24 | std::string toString() const; 25 | 26 | uint32_t dword(uint32_t id) const { 27 | return uint32_t(m_digest[4 * id + 0]) << 0 28 | | uint32_t(m_digest[4 * id + 1]) << 8 29 | | uint32_t(m_digest[4 * id + 2]) << 16 30 | | uint32_t(m_digest[4 * id + 3]) << 24; 31 | } 32 | 33 | bool operator == (const Sha1Hash& other) const { 34 | return !std::memcmp( 35 | this->m_digest.data(), 36 | other.m_digest.data(), 37 | other.m_digest.size()); 38 | } 39 | 40 | bool operator != (const Sha1Hash& other) const { 41 | return !this->operator == (other); 42 | } 43 | 44 | static Sha1Hash compute( 45 | const void* data, 46 | size_t size); 47 | 48 | static Sha1Hash compute( 49 | size_t numChunks, 50 | const Sha1Data* chunks); 51 | 52 | template 53 | static Sha1Hash compute(const T& data) { 54 | return compute(&data, sizeof(T)); 55 | } 56 | 57 | private: 58 | 59 | Sha1Digest m_digest; 60 | 61 | }; 62 | 63 | } -------------------------------------------------------------------------------- /src/util/sync/sync_recursive.cpp: -------------------------------------------------------------------------------- 1 | #include "sync_recursive.h" 2 | #include "sync_spinlock.h" 3 | 4 | namespace dxvk::sync { 5 | 6 | void RecursiveSpinlock::lock() { 7 | spin(2000, [this] { return try_lock(); }); 8 | } 9 | 10 | 11 | void RecursiveSpinlock::unlock() { 12 | if (likely(m_counter == 0)) 13 | m_owner.store(0, std::memory_order_release); 14 | else 15 | m_counter -= 1; 16 | } 17 | 18 | 19 | bool RecursiveSpinlock::try_lock() { 20 | uint32_t threadId = GetCurrentThreadId(); 21 | uint32_t expected = 0; 22 | 23 | bool status = m_owner.compare_exchange_weak( 24 | expected, threadId, std::memory_order_acquire); 25 | 26 | if (status) 27 | return true; 28 | 29 | if (expected != threadId) 30 | return false; 31 | 32 | m_counter += 1; 33 | return true; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/util/sync/sync_recursive.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../com/com_include.h" 6 | 7 | namespace dxvk::sync { 8 | 9 | /** 10 | * \brief Recursive spinlock 11 | * 12 | * Implements a spinlock that can be acquired 13 | * by the same thread multiple times. 14 | */ 15 | class RecursiveSpinlock { 16 | 17 | public: 18 | 19 | void lock(); 20 | 21 | void unlock(); 22 | 23 | bool try_lock(); 24 | 25 | private: 26 | 27 | std::atomic m_owner = { 0u }; 28 | uint32_t m_counter = { 0u }; 29 | 30 | }; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/util/sync/sync_ticketlock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../thread.h" 6 | 7 | namespace dxvk::sync { 8 | 9 | /** 10 | * \brief Ticket spinlock 11 | * 12 | * A fair spinlock implementation that should 13 | * be preferred over \ref Spinlock when one of 14 | * the threads accessing the lock is likely to 15 | * starve another. 16 | */ 17 | class TicketLock { 18 | 19 | public: 20 | 21 | void lock() { 22 | uint32_t ticket = m_counter.fetch_add(1); 23 | 24 | while (m_serving.load(std::memory_order_acquire) != ticket) 25 | continue; 26 | } 27 | 28 | void unlock() { 29 | uint32_t serveNext = m_serving.load() + 1; 30 | m_serving.store(serveNext, std::memory_order_release); 31 | } 32 | 33 | private: 34 | 35 | std::atomic m_counter = { 0 }; 36 | std::atomic m_serving = { 0 }; 37 | 38 | }; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/util/util_enum.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define ENUM_NAME(name) \ 4 | case name: return os << #name 5 | 6 | #define ENUM_DEFAULT(name) \ 7 | default: return os << static_cast(e) 8 | -------------------------------------------------------------------------------- /src/util/util_error.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace dxvk { 6 | 7 | /** 8 | * \brief DXVK error 9 | * 10 | * A generic exception class that stores a 11 | * message. Exceptions should be logged. 12 | */ 13 | class DxvkError { 14 | 15 | public: 16 | 17 | DxvkError() { } 18 | DxvkError(std::string&& message) 19 | : m_message(std::move(message)) { } 20 | 21 | const std::string& message() const { 22 | return m_message; 23 | } 24 | 25 | private: 26 | 27 | std::string m_message; 28 | 29 | }; 30 | 31 | } -------------------------------------------------------------------------------- /src/util/util_gdi.cpp: -------------------------------------------------------------------------------- 1 | #include "util_gdi.h" 2 | #include "log/log.h" 3 | 4 | namespace dxvk { 5 | 6 | HMODULE GetGDIModule() { 7 | static HMODULE module = LoadLibraryA("gdi32.dll"); 8 | return module; 9 | } 10 | 11 | NTSTATUS D3DKMTCreateDCFromMemory(D3DKMT_CREATEDCFROMMEMORY* Arg1) { 12 | static auto func = (D3DKMTCreateDCFromMemoryType) 13 | GetProcAddress(GetGDIModule(), "D3DKMTCreateDCFromMemory"); 14 | 15 | if (func != nullptr) 16 | return func(Arg1); 17 | 18 | Logger::warn("D3DKMTCreateDCFromMemory: Unable to query proc address."); 19 | return -1; 20 | } 21 | 22 | NTSTATUS D3DKMTDestroyDCFromMemory(D3DKMT_DESTROYDCFROMMEMORY* Arg1) { 23 | static auto func = (D3DKMTDestroyDCFromMemoryType) 24 | GetProcAddress(GetGDIModule(), "D3DKMTDestroyDCFromMemory"); 25 | 26 | if (func != nullptr) 27 | return func(Arg1); 28 | 29 | Logger::warn("D3DKMTDestroyDCFromMemory: Unable to query proc address."); 30 | return -1; 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /src/util/util_gdi.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace dxvk { 6 | using NTSTATUS = LONG; 7 | 8 | // Slightly modified definitions... 9 | struct D3DKMT_CREATEDCFROMMEMORY { 10 | void* pMemory; 11 | D3DFORMAT Format; 12 | UINT Width; 13 | UINT Height; 14 | UINT Pitch; 15 | HDC hDeviceDc; 16 | PALETTEENTRY* pColorTable; 17 | HDC hDc; 18 | HANDLE hBitmap; 19 | }; 20 | 21 | struct D3DKMT_DESTROYDCFROMMEMORY { 22 | HDC hDC = nullptr; 23 | HANDLE hBitmap = nullptr; 24 | }; 25 | 26 | using D3DKMTCreateDCFromMemoryType = NTSTATUS(STDMETHODCALLTYPE*) (D3DKMT_CREATEDCFROMMEMORY*); 27 | NTSTATUS D3DKMTCreateDCFromMemory (D3DKMT_CREATEDCFROMMEMORY* Arg1); 28 | 29 | using D3DKMTDestroyDCFromMemoryType = NTSTATUS(STDMETHODCALLTYPE*) (D3DKMT_DESTROYDCFROMMEMORY*); 30 | NTSTATUS D3DKMTDestroyDCFromMemory(D3DKMT_DESTROYDCFROMMEMORY* Arg1); 31 | 32 | } -------------------------------------------------------------------------------- /src/util/util_lazy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace dxvk { 6 | 7 | /** 8 | * \brief Lazy-initialized object 9 | * 10 | * Creates an object on demand with 11 | * the given constructor arguments. 12 | */ 13 | template 14 | class Lazy { 15 | 16 | public: 17 | 18 | template 19 | T& get(Args... args) { 20 | if (m_object) 21 | return *m_object; 22 | 23 | std::lock_guard lock(m_mutex); 24 | 25 | if (!m_object) { 26 | m_object = std::make_unique( 27 | std::forward(args)...); 28 | } 29 | 30 | return *m_object; 31 | } 32 | 33 | private: 34 | 35 | dxvk::mutex m_mutex; 36 | std::unique_ptr m_object; 37 | 38 | }; 39 | 40 | } -------------------------------------------------------------------------------- /src/util/util_likely.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __GNUC__ 4 | #define likely(x) __builtin_expect((x),1) 5 | #define unlikely(x) __builtin_expect((x),0) 6 | #else 7 | #define likely(x) (x) 8 | #define unlikely(x) (x) 9 | #endif 10 | -------------------------------------------------------------------------------- /src/util/util_luid.cpp: -------------------------------------------------------------------------------- 1 | #include "util_luid.h" 2 | #include "util_string.h" 3 | 4 | #include "./log/log.h" 5 | 6 | #include 7 | #include 8 | 9 | namespace dxvk { 10 | 11 | LUID GetAdapterLUID(UINT Adapter) { 12 | static dxvk::mutex s_mutex; 13 | static std::vector s_luids; 14 | 15 | std::lock_guard lock(s_mutex); 16 | uint32_t newLuidCount = Adapter + 1; 17 | 18 | while (s_luids.size() < newLuidCount) { 19 | LUID luid = { 0, 0 }; 20 | 21 | if (!::AllocateLocallyUniqueId(&luid)) 22 | Logger::err("Failed to allocate LUID"); 23 | 24 | 25 | Logger::info(str::format("Adapter LUID ", s_luids.size(), ": ", 26 | std::hex, luid.HighPart, ":", luid.LowPart, std::dec)); 27 | 28 | s_luids.push_back(luid); 29 | } 30 | 31 | return s_luids[Adapter]; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/util/util_luid.h: -------------------------------------------------------------------------------- 1 | #include "./com/com_include.h" 2 | 3 | namespace dxvk { 4 | 5 | /** 6 | * \brief Retrieves an adapter LUID 7 | * 8 | * Note that this only works reliably within the 9 | * module that this function was compiled into. 10 | * \param [in] Adapter The adapter index 11 | * \returns LUID An LUID for that adapter 12 | */ 13 | LUID GetAdapterLUID(UINT Adapter); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/util/util_math.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace dxvk { 6 | 7 | constexpr size_t CACHE_LINE_SIZE = 64; 8 | 9 | template 10 | constexpr T clamp(T n, T lo, T hi) { 11 | if (n < lo) return lo; 12 | if (n > hi) return hi; 13 | return n; 14 | } 15 | 16 | template 17 | constexpr T align(T what, U to) { 18 | return (what + to - 1) & ~(to - 1); 19 | } 20 | 21 | template 22 | constexpr T alignDown(T what, U to) { 23 | return (what / to) * to; 24 | } 25 | 26 | // Equivalent of std::clamp for use with floating point numbers 27 | // Handles (-){INFINITY,NAN} cases. 28 | // Will return min in cases of NAN, etc. 29 | inline float fclamp(float value, float min, float max) { 30 | return std::fmin( 31 | std::fmax(value, min), max); 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /src/util/util_string.cpp: -------------------------------------------------------------------------------- 1 | #include "util_string.h" 2 | 3 | namespace dxvk::str { 4 | std::string fromws(const WCHAR *ws) { 5 | size_t len = ::WideCharToMultiByte(CP_UTF8, 6 | 0, ws, -1, nullptr, 0, nullptr, nullptr); 7 | 8 | if (len <= 1) 9 | return ""; 10 | 11 | len -= 1; 12 | 13 | std::string result; 14 | result.resize(len); 15 | ::WideCharToMultiByte(CP_UTF8, 0, ws, -1, 16 | &result.at(0), len, nullptr, nullptr); 17 | return result; 18 | } 19 | 20 | 21 | void tows(const char* mbs, WCHAR* wcs, size_t wcsLen) { 22 | ::MultiByteToWideChar( 23 | CP_UTF8, 0, mbs, -1, 24 | wcs, wcsLen); 25 | } 26 | 27 | std::wstring tows(const char* mbs) { 28 | size_t len = ::MultiByteToWideChar(CP_UTF8, 29 | 0, mbs, -1, nullptr, 0); 30 | 31 | if (len <= 1) 32 | return L""; 33 | 34 | len -= 1; 35 | 36 | std::wstring result; 37 | result.resize(len); 38 | ::MultiByteToWideChar(CP_UTF8, 0, mbs, -1, 39 | &result.at(0), len); 40 | return result; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/util/util_string.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "./com/com_include.h" 8 | 9 | namespace dxvk::str { 10 | 11 | std::string fromws(const WCHAR *ws); 12 | 13 | void tows(const char* mbs, WCHAR* wcs, size_t wcsLen); 14 | 15 | template 16 | void tows(const char* mbs, WCHAR (&wcs)[N]) { 17 | return tows(mbs, wcs, N); 18 | } 19 | 20 | std::wstring tows(const char* mbs); 21 | 22 | inline void format1(std::stringstream&) { } 23 | 24 | template 25 | void format1(std::stringstream& str, const WCHAR *arg, const Tx&... args) { 26 | str << fromws(arg); 27 | format1(str, args...); 28 | } 29 | 30 | template 31 | void format1(std::stringstream& str, const T& arg, const Tx&... args) { 32 | str << arg; 33 | format1(str, args...); 34 | } 35 | 36 | template 37 | std::string format(const Args&... args) { 38 | std::stringstream stream; 39 | format1(stream, args...); 40 | return stream.str(); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/util/util_time.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #if defined(_WIN32) && !defined(__WINE__) 7 | #include 8 | #endif 9 | 10 | namespace dxvk { 11 | 12 | #if defined(_WIN32) && !defined(__WINE__) 13 | struct high_resolution_clock { 14 | static constexpr bool is_steady = true; 15 | 16 | using rep = int64_t; 17 | using period = std::nano; 18 | using duration = std::chrono::nanoseconds; 19 | using time_point = std::chrono::time_point; 20 | 21 | static inline time_point now() noexcept { 22 | // Keep the frequency static, this doesn't change at all. 23 | static const int64_t freq = getFrequency(); 24 | const int64_t counter = getCounter(); 25 | 26 | const int64_t whole = (counter / freq) * period::den; 27 | const int64_t part = (counter % freq) * period::den / freq; 28 | 29 | return time_point(duration(whole + part)); 30 | } 31 | 32 | static inline int64_t getFrequency() { 33 | LARGE_INTEGER freq; 34 | QueryPerformanceFrequency(&freq); 35 | 36 | return freq.QuadPart; 37 | } 38 | 39 | static inline int64_t getCounter() { 40 | LARGE_INTEGER count; 41 | QueryPerformanceCounter(&count); 42 | 43 | return count.QuadPart; 44 | } 45 | }; 46 | #else 47 | using high_resolution_clock = std::chrono::high_resolution_clock; 48 | #endif 49 | 50 | } -------------------------------------------------------------------------------- /src/vulkan/meson.build: -------------------------------------------------------------------------------- 1 | vkcommon_src = files([ 2 | 'vulkan_loader.cpp', 3 | 'vulkan_names.cpp', 4 | 'vulkan_presenter.cpp', 5 | ]) 6 | 7 | thread_dep = dependency('threads') 8 | 9 | vkcommon_lib = static_library('vkcommon', vkcommon_src, 10 | dependencies : [ thread_dep, lib_vulkan ], 11 | override_options : ['cpp_std='+dxvk_cpp_std], 12 | include_directories : [ dxvk_include_path ]) 13 | 14 | vkcommon_dep = declare_dependency( 15 | link_with : [ vkcommon_lib ], 16 | include_directories : [ dxvk_include_path ]) 17 | -------------------------------------------------------------------------------- /src/vulkan/vulkan_loader.cpp: -------------------------------------------------------------------------------- 1 | #include "vulkan_loader.h" 2 | 3 | namespace dxvk::vk { 4 | 5 | static const PFN_vkGetInstanceProcAddr GetInstanceProcAddr = vkGetInstanceProcAddr; 6 | 7 | PFN_vkVoidFunction LibraryLoader::sym(const char* name) const { 8 | return dxvk::vk::GetInstanceProcAddr(nullptr, name); 9 | } 10 | 11 | 12 | InstanceLoader::InstanceLoader(bool owned, VkInstance instance) 13 | : m_instance(instance), m_owned(owned) { } 14 | 15 | 16 | PFN_vkVoidFunction InstanceLoader::sym(const char* name) const { 17 | return dxvk::vk::GetInstanceProcAddr(m_instance, name); 18 | } 19 | 20 | 21 | DeviceLoader::DeviceLoader(bool owned, VkInstance instance, VkDevice device) 22 | : m_getDeviceProcAddr(reinterpret_cast( 23 | dxvk::vk::GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"))), 24 | m_device(device), m_owned(owned) { } 25 | 26 | 27 | PFN_vkVoidFunction DeviceLoader::sym(const char* name) const { 28 | return m_getDeviceProcAddr(m_device, name); 29 | } 30 | 31 | 32 | LibraryFn::LibraryFn() { } 33 | LibraryFn::~LibraryFn() { } 34 | 35 | 36 | InstanceFn::InstanceFn(bool owned, VkInstance instance) 37 | : InstanceLoader(owned, instance) { } 38 | InstanceFn::~InstanceFn() { 39 | if (m_owned) 40 | this->vkDestroyInstance(m_instance, nullptr); 41 | } 42 | 43 | 44 | DeviceFn::DeviceFn(bool owned, VkInstance instance, VkDevice device) 45 | : DeviceLoader(owned, instance, device) { } 46 | DeviceFn::~DeviceFn() { 47 | if (m_owned) 48 | this->vkDestroyDevice(m_device, nullptr); 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /src/vulkan/vulkan_names.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../util/util_enum.h" 6 | 7 | #include "vulkan_loader.h" 8 | 9 | std::ostream& operator << (std::ostream& os, VkPipelineCacheHeaderVersion e); 10 | std::ostream& operator << (std::ostream& os, VkResult e); 11 | std::ostream& operator << (std::ostream& os, VkFormat e); 12 | std::ostream& operator << (std::ostream& os, VkImageType e); 13 | std::ostream& operator << (std::ostream& os, VkImageTiling e); 14 | std::ostream& operator << (std::ostream& os, VkImageLayout e); 15 | std::ostream& operator << (std::ostream& os, VkImageViewType e); 16 | std::ostream& operator << (std::ostream& os, VkPresentModeKHR e); 17 | std::ostream& operator << (std::ostream& os, VkColorSpaceKHR e); 18 | std::ostream& operator << (std::ostream& os, VkOffset2D e); 19 | std::ostream& operator << (std::ostream& os, VkOffset3D e); 20 | std::ostream& operator << (std::ostream& os, VkExtent2D e); 21 | std::ostream& operator << (std::ostream& os, VkExtent3D e); 22 | -------------------------------------------------------------------------------- /tests/d3d11/meson.build: -------------------------------------------------------------------------------- 1 | test_d3d11_deps = [ util_dep, lib_dxgi, lib_d3d11, lib_d3dcompiler_47 ] 2 | 3 | executable('d3d11-compute'+exe_ext, files('test_d3d11_compute.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 4 | executable('d3d11-formats'+exe_ext, files('test_d3d11_formats.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 5 | executable('d3d11-map-read'+exe_ext, files('test_d3d11_map_read.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 6 | executable('d3d11-streamout'+exe_ext, files('test_d3d11_streamout.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 7 | executable('d3d11-triangle'+exe_ext, files('test_d3d11_triangle.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 8 | executable('d3d11-video'+exe_ext, files('test_d3d11_video.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 9 | 10 | install_data('video_image.raw', install_dir : get_option('bindir')) -------------------------------------------------------------------------------- /tests/d3d11/video_image.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValveSoftware/dxvk/78ef4cfd92cb7f448292aaca83091914ab271257/tests/d3d11/video_image.raw -------------------------------------------------------------------------------- /tests/d3d9/meson.build: -------------------------------------------------------------------------------- 1 | test_d3d9_deps = [ util_dep, lib_d3d9, lib_d3dcompiler_47 ] 2 | 3 | executable('d3d9-clear'+exe_ext, files('test_d3d9_clear.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 4 | executable('d3d9-buffer'+exe_ext, files('test_d3d9_buffer.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 5 | executable('d3d9-triangle'+exe_ext, files('test_d3d9_triangle.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 6 | executable('d3d9-l6v5u5'+exe_ext, files('test_d3d9_l6v5u5.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 7 | executable('d3d9-nv12'+exe_ext, files('test_d3d9_nv12.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 8 | executable('d3d9-bc-update-surface'+exe_ext, files('test_d3d9_bc_update_surface.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 9 | executable('d3d9-up'+exe_ext, files('test_d3d9_up.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 10 | -------------------------------------------------------------------------------- /tests/dxbc/meson.build: -------------------------------------------------------------------------------- 1 | test_dxbc_deps = [ dxbc_dep, dxvk_dep ] 2 | 3 | executable('dxbc-compiler'+exe_ext, files('test_dxbc_compiler.cpp'), dependencies : test_dxbc_deps, install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 4 | executable('dxbc-disasm'+exe_ext, files('test_dxbc_disasm.cpp'), dependencies : [ test_dxbc_deps, lib_d3dcompiler_47 ], install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 5 | executable('hlsl-compiler'+exe_ext, files('test_hlsl_compiler.cpp'), dependencies : [ test_dxbc_deps, lib_d3dcompiler_47 ], install : true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 6 | 7 | -------------------------------------------------------------------------------- /tests/dxbc/test_dxbc_disasm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "../../src/util/com/com_pointer.h" 11 | 12 | using namespace dxvk; 13 | 14 | int WINAPI WinMain(HINSTANCE hInstance, 15 | HINSTANCE hPrevInstance, 16 | LPSTR lpCmdLine, 17 | int nCmdShow) { 18 | int argc = 0; 19 | LPWSTR* argv = CommandLineToArgvW( 20 | GetCommandLineW(), &argc); 21 | 22 | if (argc < 2 || argc > 3) { 23 | std::cerr << "Usage: dxbc-disasm input.dxbc [output]" << std::endl; 24 | return 1; 25 | } 26 | 27 | Com assembly; 28 | Com binary; 29 | 30 | // input file 31 | if (FAILED(D3DReadFileToBlob(argv[1], &binary))) { 32 | std::cerr << "Failed to read shader" << std::endl; 33 | return 1; 34 | } 35 | 36 | HRESULT hr = D3DDisassemble( 37 | binary->GetBufferPointer(), 38 | binary->GetBufferSize(), 39 | D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING, nullptr, 40 | &assembly); 41 | 42 | if (FAILED(hr)) { 43 | std::cerr << "Failed to disassemble shader" << std::endl; 44 | return 1; 45 | } 46 | 47 | // output file variant 48 | if (argc == 3 && FAILED(D3DWriteBlobToFile(assembly.ptr(), argv[2], 1))) { 49 | std::cerr << "Failed to write shader" << std::endl; 50 | return 1; 51 | } 52 | 53 | // stdout variant 54 | if (argc == 2) { 55 | std::string data((const char *)assembly->GetBufferPointer(), assembly->GetBufferSize()); 56 | std::cout << data; 57 | } 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /tests/dxgi/meson.build: -------------------------------------------------------------------------------- 1 | test_dxgi_deps = [ util_dep, lib_dxgi ] 2 | 3 | executable('dxgi-factory'+exe_ext, files('test_dxgi_factory.cpp'), dependencies : test_dxgi_deps, install: true, gui_app : true, override_options: ['cpp_std='+dxvk_cpp_std]) 4 | -------------------------------------------------------------------------------- /tests/meson.build: -------------------------------------------------------------------------------- 1 | subdir('d3d9') 2 | subdir('d3d11') 3 | subdir('dxbc') 4 | subdir('dxgi') 5 | -------------------------------------------------------------------------------- /tests/test_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../src/util/com/com_guid.h" 6 | #include "../src/util/com/com_object.h" 7 | #include "../src/util/com/com_pointer.h" 8 | 9 | #include "../src/util/log/log.h" 10 | #include "../src/util/log/log_debug.h" 11 | 12 | #include "../src/util/rc/util_rc.h" 13 | #include "../src/util/rc/util_rc_ptr.h" 14 | 15 | #include "../src/util/util_enum.h" 16 | #include "../src/util/util_error.h" 17 | #include "../src/util/util_string.h" 18 | -------------------------------------------------------------------------------- /version.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DXVK_VERSION "@VCS_TAG@" 4 | --------------------------------------------------------------------------------