...
 
Commits (5)
......@@ -5648,6 +5648,8 @@ namespace dxvk {
D3D9SharedPS* data = reinterpret_cast<D3D9SharedPS*>(slice.mapPtr);
for (uint32_t i = 0; i < caps::TextureStageCount; i++) {
DecodeD3DCOLOR(D3DCOLOR(m_state.textureStages[i][D3DTSS_CONSTANT]), data->Stages[i].Constant);
// Flip major-ness so we can get away with a nice easy
// dot in the shader without complex access
data->Stages[i].BumpEnvMat[0][0] = bit::cast<float>(m_state.textureStages[i][D3DTSS_BUMPENVMAT00]);
......
......@@ -358,6 +358,59 @@ namespace dxvk {
}
uint32_t GetSharedConstants(SpirvModule& spvModule) {
uint32_t float_t = spvModule.defFloatType(32);
uint32_t vec2_t = spvModule.defVectorType(float_t, 2);
uint32_t vec4_t = spvModule.defVectorType(float_t, 4);
std::array<uint32_t, D3D9SharedPSStages_Count> stageMembers = {
vec2_t,
vec2_t,
float_t,
float_t,
vec4_t
};
std::array<decltype(stageMembers), caps::TextureStageCount> members;
for (auto& member : members)
member = stageMembers;
const uint32_t structType =
spvModule.defStructType(members.size() * stageMembers.size(), members[0].data());
spvModule.decorateBlock(structType);
uint32_t offset = 0;
for (uint32_t stage = 0; stage < caps::TextureStageCount; stage++) {
spvModule.memberDecorateOffset(structType, stage + 0, offset);
offset += sizeof(float) * 2;
spvModule.memberDecorateOffset(structType, stage + 1, offset);
offset += sizeof(float) * 2;
spvModule.memberDecorateOffset(structType, stage + 2, offset);
offset += sizeof(float);
spvModule.memberDecorateOffset(structType, stage + 3, offset);
offset += sizeof(float);
spvModule.memberDecorateOffset(structType, stage + 4, offset);
offset += sizeof(float) * 4;
}
uint32_t sharedState = spvModule.newVar(
spvModule.defPointerType(structType, spv::StorageClassUniform),
spv::StorageClassUniform);
spvModule.setDebugName(sharedState, "D3D9SharedPS");
return sharedState;
}
enum FFConstantMembersVS {
VSConstWorldViewMatrix = 0,
VSConstNormalMatrix = 1,
......@@ -445,6 +498,7 @@ namespace dxvk {
struct D3D9FFPixelData {
uint32_t constantBuffer = 0;
uint32_t sharedState = 0;
struct {
uint32_t textureFactor = { 0 };
......@@ -505,6 +559,8 @@ namespace dxvk {
void setupPS();
void emitPsSharedConstants();
void alphaTestPS();
bool isVS() { return m_programType == DxsoProgramType::VertexShader; }
......@@ -1380,9 +1436,14 @@ namespace dxvk {
uint32_t reg = m_module.constvec4f32(1.0f, 1.0f, 1.0f, 1.0f);
switch (arg & D3DTA_SELECTMASK) {
case D3DTA_CONSTANT:
Logger::warn("D3DTA_CONSTANT: not supported right now.");
case D3DTA_CONSTANT: {
uint32_t offset = m_module.constu32(D3D9SharedPSStages_Count * i + D3D9SharedPSStages_Constant);
uint32_t ptr = m_module.opAccessChain(m_module.defPointerType(m_vec4Type, spv::StorageClassUniform),
m_ps.sharedState, 1, &offset);
reg = m_module.opLoad(m_vec4Type, ptr);
break;
}
case D3DTA_CURRENT:
reg = current;
break;
......@@ -1780,8 +1841,29 @@ namespace dxvk {
m_resourceSlots.push_back(resource);
}
emitPsSharedConstants();
}
void D3D9FFShaderCompiler::emitPsSharedConstants() {
m_ps.sharedState = GetSharedConstants(m_module);
const uint32_t bindingId = computeResourceSlotId(
m_programType, DxsoBindingType::ConstantBuffer,
PSShared);
m_module.decorateDescriptorSet(m_ps.sharedState, 0);
m_module.decorateBinding(m_ps.sharedState, bindingId);
DxvkResourceSlot resource;
resource.slot = bindingId;
resource.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
resource.access = VK_ACCESS_UNIFORM_READ_BIT;
m_resourceSlots.push_back(resource);
}
void D3D9FFShaderCompiler::alphaTestPS() {
// Alpha testing
uint32_t boolType = m_module.defBoolType();
......
......@@ -61,6 +61,8 @@ namespace dxvk {
uint32_t GetPointCoord(SpirvModule& spvModule, std::vector<uint32_t>& entryPointInterfaces);
uint32_t GetSharedConstants(SpirvModule& spvModule);
constexpr uint32_t TCIOffset = 16;
constexpr uint32_t TCIMask = 0b111 << TCIOffset;
......
......@@ -130,8 +130,18 @@ namespace dxvk {
Vector4 textureFactor;
};
enum D3D9SharedPSStages {
D3D9SharedPSStages_Constant,
D3D9SharedPSStages_BumpEnvMat0,
D3D9SharedPSStages_BumpEnvMat1,
D3D9SharedPSStages_BumpEnvLScale,
D3D9SharedPSStages_BumpEnvLOffset,
D3D9SharedPSStages_Count,
};
struct D3D9SharedPS {
struct Stage {
float Constant[4];
float BumpEnvMat[2][2];
float BumpEnvLScale;
float BumpEnvLOffset;
......
......@@ -398,42 +398,7 @@ namespace dxvk {
void DxsoCompiler::emitPsSharedConstants() {
std::array<uint32_t, 4> stageMembers = {
getVectorTypeId({DxsoScalarType::Float32, 2}),
getVectorTypeId({DxsoScalarType::Float32, 2}),
getScalarTypeId(DxsoScalarType::Float32),
getScalarTypeId(DxsoScalarType::Float32),
};
std::array<decltype(stageMembers), caps::TextureStageCount> members;
for (auto& member : members)
member = stageMembers;
constexpr uint32_t memberCount = members.size() * stageMembers.size();
const uint32_t structType =
m_module.defStructType(memberCount, members[0].data());
m_module.decorateBlock(structType);
uint32_t offset = 0;
for (uint32_t i = 0; i < memberCount; i++) {
m_module.memberDecorateOffset(structType, i, offset);
uint32_t size = sizeof(float);
if (i % stageMembers.size() < 2)
size *= 2;
offset += size;
}
m_ps.sharedState = m_module.newVar(
m_module.defPointerType(structType, spv::StorageClassUniform),
spv::StorageClassUniform);
m_module.setDebugName(m_ps.sharedState, "D3D9SharedPS");
m_ps.sharedState = GetSharedConstants(m_module);
const uint32_t bindingId = computeResourceSlotId(
m_programInfo.type(), DxsoBindingType::ConstantBuffer,
......@@ -2587,7 +2552,7 @@ void DxsoCompiler::emitControlFlowGenericLoop(
uint32_t tc_m_n = m_module.opCompositeExtract(fl_t, m.id, 1, &i);
uint32_t offset = m_module.constu32(4 * ctx.dst.id.num + i);
uint32_t offset = m_module.constu32(D3D9SharedPSStages_Count * ctx.dst.id.num + D3D9SharedPSStages_BumpEnvMat0 + i);
uint32_t bm = m_module.opAccessChain(m_module.defPointerType(vec2_t, spv::StorageClassUniform),
m_ps.sharedState, 1, &offset);
bm = m_module.opLoad(vec2_t, bm);
......