mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-11 01:24:12 +01:00
[dxvk] Initial work on instance data fetch rates
Adds a pipeline flag to indicate that instanced draw calls need to be emulated.
This commit is contained in:
parent
0154d0856d
commit
14d5054893
@ -731,17 +731,10 @@ namespace dxvk {
|
|||||||
// set by D3D11DeviceContext::IASetVertexBuffers.
|
// set by D3D11DeviceContext::IASetVertexBuffers.
|
||||||
DxvkVertexBinding binding;
|
DxvkVertexBinding binding;
|
||||||
binding.binding = pInputElementDescs[i].InputSlot;
|
binding.binding = pInputElementDescs[i].InputSlot;
|
||||||
binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
binding.fetchRate = pInputElementDescs[i].InstanceDataStepRate;
|
||||||
|
binding.inputRate = pInputElementDescs[i].InputSlotClass == D3D11_INPUT_PER_INSTANCE_DATA
|
||||||
if (pInputElementDescs[i].InputSlotClass == D3D11_INPUT_PER_INSTANCE_DATA) {
|
? VK_VERTEX_INPUT_RATE_INSTANCE
|
||||||
binding.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
|
: VK_VERTEX_INPUT_RATE_VERTEX;
|
||||||
|
|
||||||
if (pInputElementDescs[i].InstanceDataStepRate != 1) {
|
|
||||||
Logger::warn(str::format(
|
|
||||||
"D3D11Device: Unsupported instance data step rate: ",
|
|
||||||
pInputElementDescs[i].InstanceDataStepRate));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the binding was already defined. If so, the
|
// Check if the binding was already defined. If so, the
|
||||||
// parameters must be identical (namely, the input rate).
|
// parameters must be identical (namely, the input rate).
|
||||||
|
@ -4930,6 +4930,8 @@ namespace dxvk {
|
|||||||
m_module.setDebugName(typeId, "s_push_constant");
|
m_module.setDebugName(typeId, "s_push_constant");
|
||||||
m_module.setDebugMemberName(typeId, PerVertex_Position, "instance_id");
|
m_module.setDebugMemberName(typeId, PerVertex_Position, "instance_id");
|
||||||
|
|
||||||
|
// There's only ever going to be one single push constant
|
||||||
|
// block per shader, so we'll declare the variable here
|
||||||
uint32_t ptrTypeId = m_module.defPointerType(
|
uint32_t ptrTypeId = m_module.defPointerType(
|
||||||
typeId, spv::StorageClassPushConstant);
|
typeId, spv::StorageClassPushConstant);
|
||||||
|
|
||||||
|
@ -333,6 +333,17 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cmdPushConstants(
|
||||||
|
VkPipelineLayout layout,
|
||||||
|
VkShaderStageFlags stageFlags,
|
||||||
|
uint32_t offset,
|
||||||
|
uint32_t size,
|
||||||
|
const void* pValues) {
|
||||||
|
m_vkd->vkCmdPushConstants(m_buffer,
|
||||||
|
layout, stageFlags, offset, size, pValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void cmdResolveImage(
|
void cmdResolveImage(
|
||||||
VkImage srcImage,
|
VkImage srcImage,
|
||||||
VkImageLayout srcImageLayout,
|
VkImageLayout srcImageLayout,
|
||||||
|
@ -136,6 +136,7 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
struct DxvkVertexBinding {
|
struct DxvkVertexBinding {
|
||||||
uint32_t binding;
|
uint32_t binding;
|
||||||
|
uint32_t fetchRate;
|
||||||
VkVertexInputRate inputRate;
|
VkVertexInputRate inputRate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -572,9 +572,16 @@ namespace dxvk {
|
|||||||
this->commitGraphicsState();
|
this->commitGraphicsState();
|
||||||
|
|
||||||
if (m_gpActivePipeline != VK_NULL_HANDLE) {
|
if (m_gpActivePipeline != VK_NULL_HANDLE) {
|
||||||
m_cmd->cmdDraw(
|
if (!m_flags.test(DxvkContextFlag::GpEmulateInstanceFetchRate)) {
|
||||||
vertexCount, instanceCount,
|
m_cmd->cmdDraw(
|
||||||
firstVertex, firstInstance);
|
vertexCount, instanceCount,
|
||||||
|
firstVertex, firstInstance);
|
||||||
|
} else {
|
||||||
|
static bool errorShown = false;
|
||||||
|
|
||||||
|
if (!std::exchange(errorShown, true))
|
||||||
|
Logger::warn("Dxvk: GpEmulateInstanceFetchRate not supported for direct draws");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,10 +595,17 @@ namespace dxvk {
|
|||||||
if (m_gpActivePipeline != VK_NULL_HANDLE) {
|
if (m_gpActivePipeline != VK_NULL_HANDLE) {
|
||||||
auto physicalSlice = buffer.physicalSlice();
|
auto physicalSlice = buffer.physicalSlice();
|
||||||
|
|
||||||
m_cmd->cmdDrawIndirect(
|
if (!m_flags.test(DxvkContextFlag::GpEmulateInstanceFetchRate)) {
|
||||||
physicalSlice.handle(),
|
m_cmd->cmdDrawIndirect(
|
||||||
physicalSlice.offset(),
|
physicalSlice.handle(),
|
||||||
count, stride);
|
physicalSlice.offset(),
|
||||||
|
count, stride);
|
||||||
|
} else {
|
||||||
|
static bool errorShown = false;
|
||||||
|
|
||||||
|
if (!std::exchange(errorShown, true))
|
||||||
|
Logger::warn("Dxvk: GpEmulateInstanceFetchRate not supported for indirect draws");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1042,6 +1056,8 @@ namespace dxvk {
|
|||||||
m_flags.set(
|
m_flags.set(
|
||||||
DxvkContextFlag::GpDirtyPipelineState,
|
DxvkContextFlag::GpDirtyPipelineState,
|
||||||
DxvkContextFlag::GpDirtyVertexBuffers);
|
DxvkContextFlag::GpDirtyVertexBuffers);
|
||||||
|
m_flags.clr(
|
||||||
|
DxvkContextFlag::GpEmulateInstanceFetchRate);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < attributeCount; i++) {
|
for (uint32_t i = 0; i < attributeCount; i++) {
|
||||||
m_state.gp.state.ilAttributes[i].location = attributes[i].location;
|
m_state.gp.state.ilAttributes[i].location = attributes[i].location;
|
||||||
@ -1056,6 +1072,10 @@ namespace dxvk {
|
|||||||
for (uint32_t i = 0; i < bindingCount; i++) {
|
for (uint32_t i = 0; i < bindingCount; i++) {
|
||||||
m_state.gp.state.ilBindings[i].binding = bindings[i].binding;
|
m_state.gp.state.ilBindings[i].binding = bindings[i].binding;
|
||||||
m_state.gp.state.ilBindings[i].inputRate = bindings[i].inputRate;
|
m_state.gp.state.ilBindings[i].inputRate = bindings[i].inputRate;
|
||||||
|
m_state.vi.vertexFetchRates[bindings[i].binding] = bindings[i].fetchRate;
|
||||||
|
|
||||||
|
if (bindings[i].inputRate == VK_VERTEX_INPUT_RATE_INSTANCE && bindings[i].fetchRate != 1)
|
||||||
|
m_flags.set(DxvkContextFlag::GpEmulateInstanceFetchRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = bindingCount; i < m_state.gp.state.ilBindingCount; i++)
|
for (uint32_t i = bindingCount; i < m_state.gp.state.ilBindingCount; i++)
|
||||||
|
@ -558,12 +558,12 @@ namespace dxvk {
|
|||||||
|
|
||||||
void updateShaderResources(
|
void updateShaderResources(
|
||||||
VkPipelineBindPoint bindPoint,
|
VkPipelineBindPoint bindPoint,
|
||||||
const Rc<DxvkPipelineLayout>& layout);
|
const Rc<DxvkPipelineLayout>& layout);
|
||||||
|
|
||||||
void updateShaderDescriptors(
|
void updateShaderDescriptors(
|
||||||
VkPipelineBindPoint bindPoint,
|
VkPipelineBindPoint bindPoint,
|
||||||
const DxvkBindingState& bindingState,
|
const DxvkBindingState& bindingState,
|
||||||
const Rc<DxvkPipelineLayout>& layout);
|
const Rc<DxvkPipelineLayout>& layout);
|
||||||
|
|
||||||
void updateViewports();
|
void updateViewports();
|
||||||
void updateBlendConstants();
|
void updateBlendConstants();
|
||||||
|
@ -21,16 +21,17 @@ namespace dxvk {
|
|||||||
* be updated.
|
* be updated.
|
||||||
*/
|
*/
|
||||||
enum class DxvkContextFlag : uint64_t {
|
enum class DxvkContextFlag : uint64_t {
|
||||||
GpRenderPassBound, ///< Render pass is currently bound
|
GpRenderPassBound, ///< Render pass is currently bound
|
||||||
GpDirtyPipeline, ///< Graphics pipeline binding is out of date
|
GpDirtyPipeline, ///< Graphics pipeline binding is out of date
|
||||||
GpDirtyPipelineState, ///< Graphics pipeline needs to be recompiled
|
GpDirtyPipelineState, ///< Graphics pipeline needs to be recompiled
|
||||||
GpDirtyResources, ///< Graphics pipeline resource bindings are out of date
|
GpDirtyResources, ///< Graphics pipeline resource bindings are out of date
|
||||||
GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date
|
GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date
|
||||||
GpDirtyIndexBuffer, ///< Index buffer binding are out of date
|
GpDirtyIndexBuffer, ///< Index buffer binding are out of date
|
||||||
|
GpEmulateInstanceFetchRate, ///< The current input layout uses fetch rates != 1
|
||||||
|
|
||||||
CpDirtyPipeline, ///< Compute pipeline binding are out of date
|
CpDirtyPipeline, ///< Compute pipeline binding are out of date
|
||||||
CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled
|
CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled
|
||||||
CpDirtyResources, ///< Compute pipeline resource bindings are out of date
|
CpDirtyResources, ///< Compute pipeline resource bindings are out of date
|
||||||
};
|
};
|
||||||
|
|
||||||
using DxvkContextFlags = Flags<DxvkContextFlag>;
|
using DxvkContextFlags = Flags<DxvkContextFlag>;
|
||||||
@ -42,23 +43,25 @@ namespace dxvk {
|
|||||||
uint32_t bindingMask = 0;
|
uint32_t bindingMask = 0;
|
||||||
|
|
||||||
std::array<DxvkBufferSlice,
|
std::array<DxvkBufferSlice,
|
||||||
DxvkLimits::MaxNumVertexBindings> vertexBuffers;
|
DxvkLimits::MaxNumVertexBindings> vertexBuffers = { };
|
||||||
std::array<uint32_t,
|
std::array<uint32_t,
|
||||||
DxvkLimits::MaxNumVertexBindings> vertexStrides;
|
DxvkLimits::MaxNumVertexBindings> vertexStrides = { };
|
||||||
|
std::array<uint32_t,
|
||||||
|
DxvkLimits::MaxNumVertexBindings> vertexFetchRates = { };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct DxvkViewportState {
|
struct DxvkViewportState {
|
||||||
std::array<VkViewport, DxvkLimits::MaxNumViewports> viewports;
|
std::array<VkViewport, DxvkLimits::MaxNumViewports> viewports = { };
|
||||||
std::array<VkRect2D, DxvkLimits::MaxNumViewports> scissorRects;
|
std::array<VkRect2D, DxvkLimits::MaxNumViewports> scissorRects = { };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct DxvkOutputMergerState {
|
struct DxvkOutputMergerState {
|
||||||
Rc<DxvkFramebuffer> framebuffer;
|
Rc<DxvkFramebuffer> framebuffer;
|
||||||
|
|
||||||
DxvkBlendConstants blendConstants;
|
DxvkBlendConstants blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
uint32_t stencilReference;
|
uint32_t stencilReference = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -73,9 +76,9 @@ namespace dxvk {
|
|||||||
DxvkShaderStage tes;
|
DxvkShaderStage tes;
|
||||||
DxvkShaderStage gs;
|
DxvkShaderStage gs;
|
||||||
DxvkShaderStage fs;
|
DxvkShaderStage fs;
|
||||||
|
|
||||||
DxvkGraphicsPipelineStateInfo state;
|
DxvkGraphicsPipelineStateInfo state;
|
||||||
Rc<DxvkGraphicsPipeline> pipeline;
|
Rc<DxvkGraphicsPipeline> pipeline;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ namespace dxvk {
|
|||||||
MaxNumActiveBindings = 128,
|
MaxNumActiveBindings = 128,
|
||||||
MaxNumQueuedCommandBuffers = 8,
|
MaxNumQueuedCommandBuffers = 8,
|
||||||
MaxVertexBindingStride = 2048,
|
MaxVertexBindingStride = 2048,
|
||||||
|
MaxPushConstantSize = 128,
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user