1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-11-29 19:24:10 +01:00

[dxbc] Implement sampleinfo instruction for rasterizer

This commit is contained in:
Philip Rebohle 2018-05-26 14:54:05 +02:00
parent 4ae15f3edf
commit d79f39b963
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 88 additions and 9 deletions

View File

@ -41,6 +41,13 @@ namespace dxvk {
m_oRegs.at(i) = 0;
}
// Clear spec constants
for (uint32_t i = 0; i < m_specConstants.size(); i++) {
m_specConstants.at(i) = DxbcRegisterValue {
DxbcVectorType { DxbcScalarType::Uint32, 0 },
0 };
}
this->emitInit();
}
@ -4557,15 +4564,21 @@ namespace dxvk {
DxbcRegisterValue DxbcCompiler::emitQueryTextureSamples(
const DxbcRegister& resource) {
const DxbcBufferInfo info = getBufferInfo(resource);
DxbcRegisterValue result;
result.type.ctype = DxbcScalarType::Uint32;
result.type.ccount = 1;
result.id = m_module.opImageQuerySamples(
getVectorTypeId(result.type),
m_module.opLoad(info.typeId, info.varId));
return result;
if (resource.type == DxbcOperandType::Rasterizer) {
// SPIR-V has no gl_NumSamples equivalent, so we have
// to work around it using a specialization constant
return getSpecConstant(DxvkSpecConstantId::RasterizerSampleCount);
} else {
DxbcBufferInfo info = getBufferInfo(resource);
DxbcRegisterValue result;
result.type.ctype = DxbcScalarType::Uint32;
result.type.ccount = 1;
result.id = m_module.opImageQuerySamples(
getVectorTypeId(result.type),
m_module.opLoad(info.typeId, info.varId));
return result;
}
}
@ -4778,6 +4791,43 @@ namespace dxvk {
}
DxbcRegisterValue DxbcCompiler::getSpecConstant(DxvkSpecConstantId specId) {
const uint32_t specIdOffset = uint32_t(specId) - uint32_t(DxvkSpecConstantId::SpecConstantIdMin);
// Look up spec constant in the array
DxbcRegisterValue value = m_specConstants.at(specIdOffset);
if (value.id != 0)
return value;
// Declare a new specialization constant if needed
DxbcSpecConstant info = getSpecConstantProperties(specId);
value.type.ctype = info.ctype;
value.type.ccount = info.ccount;
value.id = m_module.specConst32(
getVectorTypeId(value.type),
info.value);
m_module.decorateSpecId(value.id, uint32_t(specId));
m_module.setDebugName(value.id, info.name);
m_specConstants.at(specIdOffset) = value;
return value;
}
DxbcSpecConstant DxbcCompiler::getSpecConstantProperties(DxvkSpecConstantId specId) {
static const std::array<DxbcSpecConstant,
uint32_t(DxvkSpecConstantId::SpecConstantIdMax) -
uint32_t(DxvkSpecConstantId::SpecConstantIdMin) + 1> s_specConstants = {{
{ DxbcScalarType::Uint32, 1, 1, "RasterizerSampleCount" },
}};
return s_specConstants.at(uint32_t(specId) - uint32_t(DxvkSpecConstantId::SpecConstantIdMin));
}
void DxbcCompiler::emitInputSetup() {
// Copy all defined v# registers into the input array
const uint32_t vecTypeId = m_module.defVectorType(m_module.defFloatType(32), 4);

View File

@ -96,6 +96,20 @@ namespace dxvk {
};
/**
* \brief Specialization constant properties
*
* Stores the name, data type and initial
* value of a specialization constant.
*/
struct DxbcSpecConstant {
DxbcScalarType ctype;
uint32_t ccount;
uint32_t value;
const char* name;
};
/**
* \brief Vertex shader-specific structure
*/
@ -384,6 +398,13 @@ namespace dxvk {
// currently active if-else blocks and loops.
std::vector<DxbcCfgBlock> m_controlFlowBlocks;
///////////////////////////////////////////////
// Specialization constants. These are defined
// as needed by the getSpecConstant method.
std::array<DxbcRegisterValue,
uint32_t(DxvkSpecConstantId::SpecConstantIdMax) -
uint32_t(DxvkSpecConstantId::SpecConstantIdMin) + 1> m_specConstants;
///////////////////////////////////////////////////////////
// Array of input values. Since v# registers are indexable
// in DXBC, we need to copy them into an array first.
@ -848,6 +869,14 @@ namespace dxvk {
const DxbcRegister& reg,
DxbcRegisterValue value);
////////////////////////////////////////
// Spec constant declaration and access
DxbcRegisterValue getSpecConstant(
DxvkSpecConstantId specId);
DxbcSpecConstant getSpecConstantProperties(
DxvkSpecConstantId specId);
////////////////////////////
// Input/output preparation
void emitInputSetup();