From 41132b8c13c18f5ed359be4027190d8a1fd89a66 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 10 Apr 2018 18:46:39 +0200 Subject: [PATCH] [dxgi] Re-implement presentation shaders in GLSL --- src/dxgi/dxgi_presenter.cpp | 184 +--------------------- src/dxgi/meson.build | 7 +- src/dxgi/shaders/dxgi_presenter_frag.frag | 11 ++ src/dxgi/shaders/dxgi_presenter_vert.vert | 16 ++ 4 files changed, 40 insertions(+), 178 deletions(-) create mode 100644 src/dxgi/shaders/dxgi_presenter_frag.frag create mode 100644 src/dxgi/shaders/dxgi_presenter_vert.vert diff --git a/src/dxgi/dxgi_presenter.cpp b/src/dxgi/dxgi_presenter.cpp index f9a8ccc7..f6b83ddf 100644 --- a/src/dxgi/dxgi_presenter.cpp +++ b/src/dxgi/dxgi_presenter.cpp @@ -2,6 +2,9 @@ #include "../spirv/spirv_module.h" +#include +#include + namespace dxvk { DxgiPresenter::DxgiPresenter( @@ -342,190 +345,17 @@ namespace dxvk { Rc DxgiPresenter::createVertexShader() { - SpirvModule module; + const SpirvCodeBuffer codeBuffer(dxgi_presenter_vert); - // Set up basic vertex shader capabilities - module.enableCapability(spv::CapabilityShader); - module.setMemoryModel( - spv::AddressingModelLogical, - spv::MemoryModelGLSL450); - - // ID of the entry point (function) - uint32_t entryPointId = module.allocateId(); - - // Data type definitions - uint32_t typeVoid = module.defVoidType(); - uint32_t typeU32 = module.defIntType(32, 0); - uint32_t typeF32 = module.defFloatType(32); - uint32_t typeVec2 = module.defVectorType(typeF32, 2); - uint32_t typeVec4 = module.defVectorType(typeF32, 4); - uint32_t typeVec4Arr4 = module.defArrayType(typeVec4, module.constu32(4)); - uint32_t typeFn = module.defFunctionType(typeVoid, 0, nullptr); - - // Pointer type definitions - uint32_t ptrInputU32 = module.defPointerType(typeU32, spv::StorageClassInput); - uint32_t ptrOutputVec2 = module.defPointerType(typeVec2, spv::StorageClassOutput); - uint32_t ptrOutputVec4 = module.defPointerType(typeVec4, spv::StorageClassOutput); - uint32_t ptrPrivateVec4 = module.defPointerType(typeVec4, spv::StorageClassPrivate); - uint32_t ptrPrivateArr4 = module.defPointerType(typeVec4Arr4, spv::StorageClassPrivate); - - // Input variable: VertexIndex - uint32_t inVertexId = module.newVar( - ptrInputU32, spv::StorageClassInput); - module.decorateBuiltIn(inVertexId, spv::BuiltInVertexIndex); - - // Output variable: Position - uint32_t outPosition = module.newVar( - ptrOutputVec4, spv::StorageClassOutput); - module.decorateBuiltIn(outPosition, spv::BuiltInPosition); - - // Output variable: Texture coordinates - uint32_t outTexCoord = module.newVar( - ptrOutputVec2, spv::StorageClassOutput); - module.decorateLocation(outTexCoord, 0); - - // Temporary variable: Vertex array - uint32_t varVertexArray = module.newVar( - ptrPrivateArr4, spv::StorageClassPrivate); - - // Scalar constants - uint32_t constF32Zero = module.constf32( 0.0f); - uint32_t constF32Half = module.constf32( 0.5f); - uint32_t constF32Pos1 = module.constf32( 1.0f); - uint32_t constF32Neg1 = module.constf32(-1.0f); - - // Vector constants - uint32_t constVec2HalfIds[2] = { constF32Half, constF32Half }; - uint32_t constVec2Half = module.constComposite(typeVec2, 2, constVec2HalfIds); - - // Construct vertex array - uint32_t vertexData[16] = { - constF32Neg1, constF32Neg1, constF32Zero, constF32Pos1, - constF32Neg1, constF32Pos1, constF32Zero, constF32Pos1, - constF32Pos1, constF32Neg1, constF32Zero, constF32Pos1, - constF32Pos1, constF32Pos1, constF32Zero, constF32Pos1, - }; - - uint32_t vertexConstants[4] = { - module.constComposite(typeVec4, 4, vertexData + 0), - module.constComposite(typeVec4, 4, vertexData + 4), - module.constComposite(typeVec4, 4, vertexData + 8), - module.constComposite(typeVec4, 4, vertexData + 12), - }; - - uint32_t vertexArray = module.constComposite( - typeVec4Arr4, 4, vertexConstants); - - - // Function header - module.functionBegin(typeVoid, entryPointId, typeFn, spv::FunctionControlMaskNone); - module.opLabel(module.allocateId()); - module.opStore(varVertexArray, vertexArray); - - // Load position of the current vertex - uint32_t tmpVertexId = module.opLoad(typeU32, inVertexId); - uint32_t tmpVertexPtr = module.opAccessChain( - ptrPrivateVec4, varVertexArray, 1, &tmpVertexId); - uint32_t tmpVertexPos = module.opLoad(typeVec4, tmpVertexPtr); - module.opStore(outPosition, tmpVertexPos); - - // Compute texture coordinates - uint32_t swizzleIndices[2] = { 0, 1 }; - uint32_t tmpTexCoord = module.opVectorShuffle(typeVec2, - tmpVertexPos, tmpVertexPos, 2, swizzleIndices); - tmpTexCoord = module.opFMul(typeVec2, tmpTexCoord, constVec2Half); - tmpTexCoord = module.opFAdd(typeVec2, tmpTexCoord, constVec2Half); - module.opStore(outTexCoord, tmpTexCoord); - - module.opReturn(); - module.functionEnd(); - - // Register function entry point - std::array interfaces = { - inVertexId, outPosition, outTexCoord, - }; - - module.addEntryPoint(entryPointId, spv::ExecutionModelVertex, - "main", interfaces.size(), interfaces.data()); - - // Create the actual shader module return m_device->createShader( VK_SHADER_STAGE_VERTEX_BIT, 0, nullptr, { 0u, 1u }, - module.compile()); + codeBuffer); } Rc DxgiPresenter::createFragmentShader() { - SpirvModule module; - - module.enableCapability(spv::CapabilityShader); - module.setMemoryModel( - spv::AddressingModelLogical, - spv::MemoryModelGLSL450); - - uint32_t entryPointId = module.allocateId(); - - // Data type definitions - uint32_t typeVoid = module.defVoidType(); - uint32_t typeF32 = module.defFloatType(32); - uint32_t typeVec2 = module.defVectorType(typeF32, 2); - uint32_t typeVec4 = module.defVectorType(typeF32, 4); - uint32_t typeFn = module.defFunctionType(typeVoid, 0, nullptr); - uint32_t typeSampler = module.defSamplerType(); - uint32_t typeTexture = module.defImageType( - typeF32, spv::Dim2D, 0, 0, 0, 1, spv::ImageFormatUnknown); - uint32_t typeSampledTex = module.defSampledImageType(typeTexture); - - // Pointer type definitions - uint32_t ptrInputVec2 = module.defPointerType(typeVec2, spv::StorageClassInput); - uint32_t ptrOutputVec4 = module.defPointerType(typeVec4, spv::StorageClassOutput); - uint32_t ptrSampler = module.defPointerType(typeSampler, spv::StorageClassUniformConstant); - uint32_t ptrTexture = module.defPointerType(typeTexture, spv::StorageClassUniformConstant); - - // Sampler - uint32_t rcSampler = module.newVar(ptrSampler, spv::StorageClassUniformConstant); - module.decorateDescriptorSet(rcSampler, 0); - module.decorateBinding(rcSampler, BindingIds::Sampler); - - // Texture - uint32_t rcTexture = module.newVar(ptrTexture, spv::StorageClassUniformConstant); - module.decorateDescriptorSet(rcTexture, 0); - module.decorateBinding(rcTexture, BindingIds::Texture); - - // Input variable: Texture coordinates - uint32_t inTexCoord = module.newVar( - ptrInputVec2, spv::StorageClassInput); - module.decorateLocation(inTexCoord, 0); - - // Output variable: Final color - uint32_t outColor = module.newVar( - ptrOutputVec4, spv::StorageClassOutput); - module.decorateLocation(outColor, 0); - - // Function header - module.functionBegin(typeVoid, entryPointId, typeFn, spv::FunctionControlMaskNone); - module.opLabel(module.allocateId()); - - // Load texture coordinates - module.opStore(outColor, - module.opImageSampleImplicitLod( - typeVec4, - module.opSampledImage( - typeSampledTex, - module.opLoad(typeTexture, rcTexture), - module.opLoad(typeSampler, rcSampler)), - module.opLoad(typeVec2, inTexCoord), - SpirvImageOperands())); - - module.opReturn(); - module.functionEnd(); - - // Register function entry point - std::array interfaces = { inTexCoord, outColor }; - - module.addEntryPoint(entryPointId, spv::ExecutionModelFragment, - "main", interfaces.size(), interfaces.data()); + const SpirvCodeBuffer codeBuffer(dxgi_presenter_frag); // Shader resource slots std::array resourceSlots = {{ @@ -539,7 +369,7 @@ namespace dxvk { resourceSlots.size(), resourceSlots.data(), { 1u, 1u }, - module.compile()); + codeBuffer); } } diff --git a/src/dxgi/meson.build b/src/dxgi/meson.build index 16b43351..2d6a2262 100644 --- a/src/dxgi/meson.build +++ b/src/dxgi/meson.build @@ -1,3 +1,8 @@ +dxgi_shaders = files([ + 'shaders/dxgi_presenter_frag.frag', + 'shaders/dxgi_presenter_vert.vert', +]) + dxgi_src = [ 'dxgi_adapter.cpp', 'dxgi_device.cpp', @@ -9,7 +14,7 @@ dxgi_src = [ 'dxgi_swapchain.cpp', ] -dxgi_dll = shared_library('dxgi', dxgi_src, +dxgi_dll = shared_library('dxgi', dxgi_src, glsl_generator.process(dxgi_shaders), name_prefix : '', link_with : [ util_lib ], dependencies : [ dxvk_dep ], diff --git a/src/dxgi/shaders/dxgi_presenter_frag.frag b/src/dxgi/shaders/dxgi_presenter_frag.frag new file mode 100644 index 00000000..831862aa --- /dev/null +++ b/src/dxgi/shaders/dxgi_presenter_frag.frag @@ -0,0 +1,11 @@ +#version 450 + +layout(binding = 0) uniform sampler s_sampler; +layout(binding = 1) uniform texture2D t_texture; + +layout(location = 0) in vec2 i_texcoord; +layout(location = 0) out vec4 o_color; + +void main() { + o_color = texture(sampler2D(t_texture, s_sampler), i_texcoord); +} \ No newline at end of file diff --git a/src/dxgi/shaders/dxgi_presenter_vert.vert b/src/dxgi/shaders/dxgi_presenter_vert.vert new file mode 100644 index 00000000..98b6b325 --- /dev/null +++ b/src/dxgi/shaders/dxgi_presenter_vert.vert @@ -0,0 +1,16 @@ +#version 450 + +const vec4 g_vpos[4] = { + vec4(-1.0f, -1.0f, 0.0f, 1.0f), + vec4(-1.0f, 1.0f, 0.0f, 1.0f), + vec4( 1.0f, -1.0f, 0.0f, 1.0f), + vec4( 1.0f, 1.0f, 0.0f, 1.0f), +}; + +layout(location = 0) out vec2 o_texcoord; + +void main() { + vec4 pos = g_vpos[gl_VertexIndex]; + o_texcoord = 0.5f + 0.5f * pos.xy; + gl_Position = pos; +} \ No newline at end of file