@@ -22,6 +22,14 @@ namespace dxvk {
2222 };
2323
2424
25+ struct DxvkMetaInputAttachmentImageCopyPushArgs {
26+ ir::SsaDef srcOffset = { };
27+ ir::SsaDef dstOffset = { };
28+ ir::SsaDef srcLayer = { };
29+ ir::SsaDef dstLayer = { };
30+ };
31+
32+
2533 static DxvkMetaImageCopyPushArgs loadImageCopyPushArgs (ir::Builder& builder, DxvkBuiltInShader& helper) {
2634 ir::BasicType coordType (ir::ScalarType::eU32, 3u );
2735
@@ -34,6 +42,18 @@ namespace dxvk {
3442 }
3543
3644
45+ static DxvkMetaInputAttachmentImageCopyPushArgs loadInputAttachmentImageCopyPushArgs (ir::Builder& builder, DxvkBuiltInShader& helper) {
46+ ir::BasicType coordType (ir::ScalarType::eU32, 2u );
47+
48+ DxvkMetaInputAttachmentImageCopyPushArgs result = { };
49+ result.srcOffset = helper.declarePushData (builder, coordType, offsetof (DxvkMetaInputAttachmentImageCopy::Args, srcOffset), " src_offset" );
50+ result.dstOffset = helper.declarePushData (builder, coordType, offsetof (DxvkMetaInputAttachmentImageCopy::Args, dstOffset), " dst_offset" );
51+ result.srcLayer = helper.declarePushData (builder, ir::ScalarType::eU32, offsetof (DxvkMetaInputAttachmentImageCopy::Args, srcLayer), " src_layer" );
52+ result.dstLayer = helper.declarePushData (builder, ir::ScalarType::eU32, offsetof (DxvkMetaInputAttachmentImageCopy::Args, dstLayer), " dst_layer" );
53+ return result;
54+ }
55+
56+
3757 static DxvkMetaBufferToImageCopyPushArgs loadBufferToImageCopyPushArgs (ir::Builder& builder, DxvkBuiltInShader& helper) {
3858 ir::BasicType coordType2D (ir::ScalarType::eU32, 2u );
3959 ir::BasicType coordType3D (ir::ScalarType::eU32, 3u );
@@ -190,6 +210,19 @@ namespace dxvk {
190210 }
191211
192212
213+ DxvkMetaInputAttachmentImageCopy DxvkMetaCopyObjects::getPipeline (const DxvkMetaInputAttachmentImageCopy::Key& key) {
214+ std::lock_guard<dxvk::mutex> lock (m_mutex);
215+
216+ auto entry = m_inputAttachmentImageCopyPipelines.find (key);
217+ if (entry != m_inputAttachmentImageCopyPipelines.end ())
218+ return entry->second ;
219+
220+ DxvkMetaInputAttachmentImageCopy pipeline = createInputAttachmentCopyPipeline (key);
221+ m_inputAttachmentImageCopyPipelines.insert ({ key, pipeline });
222+ return pipeline;
223+ }
224+
225+
193226 DxvkMetaBufferToImageCopy DxvkMetaCopyObjects::getPipeline (const DxvkMetaBufferToImageCopy::Key& key) {
194227 std::lock_guard<dxvk::mutex> lock (m_mutex);
195228
@@ -278,6 +311,25 @@ namespace dxvk {
278311 }
279312
280313
314+ std::vector<uint32_t > DxvkMetaCopyObjects::createVsCopyInputAttachment (
315+ const DxvkPipelineLayout* layout,
316+ const DxvkMetaInputAttachmentImageCopy::Key& key) {
317+ dxbc_spv::ir::Builder builder;
318+ DxvkBuiltInShader helper (m_device, layout, getName (key, " vs" ));
319+
320+ helper.buildFullscreenVertexShader (builder);
321+
322+ ir::ResourceKind srcKind = helper.determineResourceKind (key.srcViewType , VK_SAMPLE_COUNT_1_BIT );
323+
324+ if (ir::resourceIsLayered (srcKind)) {
325+ DxvkMetaInputAttachmentImageCopyPushArgs pushArgs = loadInputAttachmentImageCopyPushArgs (builder, helper);
326+ helper.exportBuiltIn (builder, ir::BuiltIn::eLayerIndex, pushArgs.srcLayer );
327+ }
328+
329+ return helper.buildShader (builder);
330+ }
331+
332+
281333 std::vector<uint32_t > DxvkMetaCopyObjects::createVsCopyBufferToImage (
282334 const DxvkPipelineLayout* layout,
283335 const DxvkMetaBufferToImageCopy::Key& key) {
@@ -356,6 +408,59 @@ namespace dxvk {
356408 }
357409
358410
411+ std::vector<uint32_t > DxvkMetaCopyObjects::createPsCopyInputAttachment (
412+ const DxvkPipelineLayout* layout,
413+ const DxvkMetaInputAttachmentImageCopy::Key& key) {
414+ dxbc_spv::ir::Builder builder;
415+
416+ DxvkBuiltInShader helper (m_device, layout, getName (key, " ps" ));
417+ helper.buildPixelShader (builder);
418+
419+ DxvkMetaInputAttachmentImageCopyPushArgs pushArgs = loadInputAttachmentImageCopyPushArgs (builder, helper);
420+
421+ ir::ResourceKind kind = helper.determineResourceKind (key.dstViewType , VK_SAMPLE_COUNT_1_BIT );
422+ uint32_t coordDims = ir::resourceCoordComponentCount (kind);
423+
424+ ir::BasicType coordTypeF (ir::ScalarType::eF32, 4u );
425+ ir::BasicType coordTypeU (ir::ScalarType::eU32, coordDims);
426+
427+ ir::SsaDef coord = helper.declareBuiltInInput (builder, coordTypeF, ir::BuiltIn::ePosition);
428+ coord = helper.emitExtractVector (builder, coord, 0u , coordDims);
429+ coord = builder.add (ir::Op::ConvertFtoI (coordTypeU, coord));
430+ coord = builder.add (ir::Op::ISub (coordTypeU, coord, helper.emitExtractVector (builder, pushArgs.srcOffset , 0u , coordDims)));
431+ coord = builder.add (ir::Op::IAdd (coordTypeU, coord, helper.emitExtractVector (builder, pushArgs.dstOffset , 0u , coordDims)));
432+
433+ ir::SsaDef layer = resourceIsLayered (kind) ? pushArgs.dstLayer : ir::SsaDef ();
434+ ir::BasicType valueType (helper.determineSampledType (key.dstFormat , VK_IMAGE_ASPECT_COLOR_BIT ), 4u );
435+
436+ ir::SsaDef imgSrc = helper.declareInputTarget (builder, 0u , " img_src" ,
437+ key.srcAttachment , key.colorFormats [key.srcAttachment ], VK_SAMPLE_COUNT_1_BIT );
438+ ir::SsaDef imgDst = helper.declareImageUav (builder, 1u , " img_dst" ,
439+ key.dstViewType , key.dstFormat );
440+
441+ ir::SsaDef value = builder.add (ir::Op::InputTargetLoad (valueType, imgSrc, ir::SsaDef ()));
442+ value = helper.emitFormatVector (builder, key.dstFormat , value);
443+
444+ auto resultType = builder.getOp (value).getType ();
445+
446+ // Emit linear to sRGB conversion as necessary
447+ auto srcFormatInfo = lookupFormatInfo (key.colorFormats [key.srcAttachment ]);
448+ auto dstFormatInfo = lookupFormatInfo (key.dstFormat );
449+
450+ ir::SsaDef conversionFunction = { };
451+
452+ if (srcFormatInfo->flags .test (DxvkFormatFlag::ColorSpaceSrgb)
453+ && !dstFormatInfo->flags .test (DxvkFormatFlag::ColorSpaceSrgb))
454+ conversionFunction = helper.buildLinearToSrgbFn (builder, resultType);
455+
456+ if (conversionFunction)
457+ value = builder.add (ir::Op::FunctionCall (resultType, conversionFunction).addOperand (value));
458+
459+ builder.add (ir::Op::ImageStore (imgDst, layer, coord, value));
460+ return helper.buildShader (builder);
461+ }
462+
463+
359464 std::vector<uint32_t > DxvkMetaCopyObjects::createPsCopyBufferToImage (
360465 const DxvkPipelineLayout* layout,
361466 const DxvkMetaBufferToImageCopy::Key& key) {
@@ -835,6 +940,43 @@ namespace dxvk {
835940 }
836941
837942
943+ DxvkMetaInputAttachmentImageCopy DxvkMetaCopyObjects::createInputAttachmentCopyPipeline (const DxvkMetaInputAttachmentImageCopy::Key& key) {
944+ static const std::array<DxvkDescriptorSetLayoutBinding, 2 > bindings = {{
945+ { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT , 1 , VK_SHADER_STAGE_FRAGMENT_BIT },
946+ { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE , 1 , VK_SHADER_STAGE_FRAGMENT_BIT },
947+ }};
948+
949+ // Disable depth-stencil writes
950+ VkPipelineDepthStencilStateCreateInfo dsState = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO };
951+ dsState.depthTestEnable = VK_FALSE ;
952+ dsState.depthWriteEnable = VK_FALSE ;
953+ dsState.stencilTestEnable = VK_FALSE ;
954+
955+ DxvkMetaInputAttachmentImageCopy pipeline;
956+ pipeline.layout = m_device->createBuiltInPipelineLayout (0u ,
957+ VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_VERTEX_BIT ,
958+ sizeof (DxvkMetaInputAttachmentImageCopy::Args), bindings.size (), bindings.data ());
959+
960+ auto vsSpirv = createVsCopyInputAttachment (pipeline.layout , key);
961+ auto psSpirv = createPsCopyInputAttachment (pipeline.layout , key);
962+
963+ // Disable all color writes
964+ std::array<VkPipelineColorBlendAttachmentState, MaxNumRenderTargets> cbAttachments = { };
965+
966+ util::DxvkBuiltInGraphicsState state = { };
967+ state.vs = vsSpirv;
968+ state.fs = psSpirv;
969+ state.dsState = &dsState;
970+ state.cbAttachment = cbAttachments.data ();
971+ state.sampleCount = VK_SAMPLE_COUNT_1_BIT ;
972+ state.depthFormat = key.depthFormat ;
973+ state.colorFormats = key.colorFormats ;
974+
975+ pipeline.pipeline = m_device->createBuiltInGraphicsPipeline (pipeline.layout , state);
976+ return pipeline;
977+ }
978+
979+
838980 DxvkMetaImageCopy DxvkMetaCopyObjects::createImageCopyPipeline (const DxvkMetaImageCopy::Key& key) {
839981 static const std::array<DxvkDescriptorSetLayoutBinding, 2 > bindings = {{
840982 { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE , 1 , VK_SHADER_STAGE_FRAGMENT_BIT },
@@ -926,6 +1068,17 @@ namespace dxvk {
9261068 }
9271069
9281070
1071+ std::string DxvkMetaCopyObjects::getName (const DxvkMetaInputAttachmentImageCopy::Key& key, const char * type) {
1072+ std::stringstream name;
1073+ name << " meta_" << type << " _copy_input_attachment" ;
1074+ name << " _" << str::format (key.srcViewType ).substr (std::strlen (" VK_IMAGE_VIEW_TYPE_" ));
1075+ name << " _to_" << str::format (key.dstViewType ).substr (std::strlen (" VK_IMAGE_VIEW_TYPE_" ));
1076+ name << " _" << str::format (key.colorFormats [key.srcAttachment ]).substr (std::strlen (" VK_FORMAT_" ));
1077+ name << " _rt" << key.srcAttachment ;
1078+ return str::tolower (name.str ());
1079+ }
1080+
1081+
9291082 std::string DxvkMetaCopyObjects::getName (const DxvkMetaBufferToImageCopy::Key& key, const char * type) {
9301083 std::stringstream name;
9311084 name << " meta_" << type << " _copy_buffer_to_image" ;
0 commit comments