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:
parent
4ae15f3edf
commit
d79f39b963
@ -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);
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user