void* default_depth_stencil;
void* default_blend;
void* default_sampler;
- void* ld_sampler;
- void * default_shaders[D3D11_STAGES];
+ void* default_shaders[D3D11_STAGES];
// derived state
int primitive_mode;
struct pipe_vertex_buffer vertex_buffers[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
struct pipe_resource* so_buffers[D3D11_SO_BUFFER_SLOT_COUNT];
struct pipe_sampler_view* sampler_views[D3D11_STAGES][D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
- struct
- {
- void* ld; // accessed with a -1 index from v
- void* v[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];
- } sampler_csos[D3D11_STAGES];
- struct pipe_resource * buffers[D3D11_SO_BUFFER_SLOT_COUNT];
+ void* sampler_csos[D3D11_STAGES][D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];
+ struct pipe_resource* buffers[D3D11_SO_BUFFER_SLOT_COUNT];
unsigned num_shader_resource_views[D3D11_STAGES];
unsigned num_samplers[D3D11_STAGES];
unsigned num_vertex_buffers;
samplerd.min_lod = -FLT_MAX;
samplerd.max_lod = FLT_MAX;
samplerd.max_anisotropy = 1;
- ld_sampler = pipe->create_sampler_state(pipe, &samplerd);
for(unsigned s = 0; s < D3D11_STAGES; ++s)
- {
- sampler_csos[s].ld = ld_sampler;
for(unsigned i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i)
- sampler_csos[s].v[i] = default_sampler;
- }
+ sampler_csos[s][i] = default_sampler;
// TODO: should this really be empty shaders, or should they be all-passthrough?
memset(default_shaders, 0, sizeof(default_shaders));
if(pipe->bind_geometry_sampler_states)
pipe->bind_geometry_sampler_states(pipe, 0, 0);
pipe->delete_sampler_state(pipe, default_sampler);
- pipe->delete_sampler_state(pipe, ld_sampler);
pipe->bind_fs_state(pipe, 0);
pipe->delete_fs_state(pipe, default_shaders[PIPE_SHADER_FRAGMENT]);
if(samplers[s][start + i].p != samps[i])
{
samplers[s][start + i] = samps[i];
- sampler_csos[s].v[start + i] = samps[i] ? samps[i]->object : default_sampler;
+ sampler_csos[s][start + i] = samps[i] ? samps[i]->object : default_sampler;
last_different = i;
}
- if(last_different >= 0)
- {
- num_samplers[s] = std::max(num_samplers[s], start + last_different + 1);
- update_flags |= 1 << (UPDATE_SAMPLERS_SHIFT + s);
- }
+ }
+ if(last_different >= 0)
+ {
+ num_samplers[s] = std::max(num_samplers[s], start + last_different + 1);
+ update_flags |= 1 << (UPDATE_SAMPLERS_SHIFT + s);
}
}
--num_shader_resource_views[s];
if((1 << s) & caps.stages_with_sampling)
{
- struct pipe_sampler_view* views_to_bind[PIPE_MAX_SAMPLERS];
- unsigned num_views_to_bind = shaders[s] ? shaders[s]->slot_to_resource.size() : 0;
- for(unsigned i = 0; i < num_views_to_bind; ++i)
- {
- views_to_bind[i] = sampler_views[s][shaders[s]->slot_to_resource[i]];
- }
+ const unsigned num_views_to_bind = num_shader_resource_views[s];
switch(s)
{
case PIPE_SHADER_VERTEX:
- pipe->set_vertex_sampler_views(pipe, num_views_to_bind, views_to_bind);
+ pipe->set_vertex_sampler_views(pipe, num_views_to_bind, sampler_views[s]);
break;
case PIPE_SHADER_FRAGMENT:
- pipe->set_fragment_sampler_views(pipe, num_views_to_bind, views_to_bind);
+ pipe->set_fragment_sampler_views(pipe, num_views_to_bind, sampler_views[s]);
break;
case PIPE_SHADER_GEOMETRY:
- pipe->set_geometry_sampler_views(pipe, num_views_to_bind, views_to_bind);
+ pipe->set_geometry_sampler_views(pipe, num_views_to_bind, sampler_views[s]);
break;
}
}
if(update_flags & (1 << (UPDATE_SAMPLERS_SHIFT + s)))
{
- while(num_samplers[s] && !sampler_csos[s].v[num_samplers[s] - 1])
+ while(num_samplers[s] && !sampler_csos[s][num_samplers[s] - 1])
--num_samplers[s];
if((1 << s) & caps.stages_with_sampling)
{
- void* samplers_to_bind[PIPE_MAX_SAMPLERS];
- unsigned num_samplers_to_bind = shaders[s] ? shaders[s]->slot_to_sampler.size() : 0;
- for(unsigned i = 0; i < num_samplers_to_bind; ++i)
- {
- // index can be -1 to access sampler_csos[s].ld
- samplers_to_bind[i] = *(sampler_csos[s].v + shaders[s]->slot_to_sampler[i]);
- }
+ const unsigned num_samplers_to_bind = num_samplers[s];
switch(s)
{
case PIPE_SHADER_VERTEX:
- pipe->bind_vertex_sampler_states(pipe, num_samplers_to_bind, samplers_to_bind);
+ pipe->bind_vertex_sampler_states(pipe, num_samplers_to_bind, sampler_csos[s]);
break;
case PIPE_SHADER_FRAGMENT:
- pipe->bind_fragment_sampler_states(pipe, num_samplers_to_bind, samplers_to_bind);
+ pipe->bind_fragment_sampler_states(pipe, num_samplers_to_bind, sampler_csos[s]);
break;
case PIPE_SHADER_GEOMETRY:
- pipe->bind_geometry_sampler_states(pipe, num_samplers_to_bind, samplers_to_bind);
+ pipe->bind_geometry_sampler_states(pipe, num_samplers_to_bind, sampler_csos[s]);
break;
}
}
if(samplers[s][i] == state)
{
samplers[s][i].p = NULL;
- sampler_csos[s].v[i] = NULL;
+ sampler_csos[s][i] = NULL;
update_flags |= (1 << (UPDATE_SAMPLERS_SHIFT + s));
}
}
std::vector<struct ureg_dst> temps;
std::vector<struct ureg_dst> outputs;
std::vector<struct ureg_src> inputs;
+ std::vector<struct ureg_src> resources;
std::vector<struct ureg_src> samplers;
std::vector<std::pair<unsigned, unsigned> > targets; // first is normal, second shadow/comparison
std::vector<unsigned> sampler_modes; // 0 = normal, 1 = shadow/comparison
return (int)op.indices[0].disp;
}
- int _texslot(bool have_sampler = true)
+ unsigned tex_target(unsigned resource, unsigned sampler)
{
- std::map<std::pair<int, int>, int>::iterator i;
- i = program.resource_sampler_to_slot.find(std::make_pair(_idx(SM4_FILE_RESOURCE, 2), have_sampler ? _idx(SM4_FILE_SAMPLER, 3) : -1));
- check(i != program.resource_sampler_to_slot.end());
- return i->second;
+ unsigned shadow = sampler_modes[sampler];
+ unsigned target = shadow ? targets[resource].second : targets[resource].first;
+ check(target);
+ return target;
}
- unsigned tex_target(unsigned texslot)
+ enum pipe_type res_return_type(unsigned type)
{
- unsigned mode = sampler_modes[program.slot_to_sampler[texslot]];
- unsigned target;
- if(mode)
- target = targets[program.slot_to_resource[texslot]].second;
- else
- target = targets[program.slot_to_resource[texslot]].first;
- check(target);
- return target;
+ switch(type)
+ {
+ case D3D_RETURN_TYPE_UNORM: return PIPE_TYPE_UNORM;
+ case D3D_RETURN_TYPE_SNORM: return PIPE_TYPE_SNORM;
+ case D3D_RETURN_TYPE_SINT: return PIPE_TYPE_SINT;
+ case D3D_RETURN_TYPE_UINT: return PIPE_TYPE_UINT;
+ case D3D_RETURN_TYPE_FLOAT: return PIPE_TYPE_FLOAT;
+ default:
+ fail("invalid resource return type");
+ return PIPE_TYPE_FLOAT;
+ }
}
std::vector<struct ureg_dst> insn_tmps;
}
break;
case SM4_OPCODE_RESINFO:
- {
- std::map<int, int>::iterator i;
- i = program.resource_to_slot.find(_idx(SM4_FILE_RESOURCE, 2));
- check(i != program.resource_to_slot.end());
- unsigned texslot = i->second;
-
- // no driver actually provides this, unfortunately
- ureg_TXQ(ureg, _dst(), tex_target(texslot), _src(1), samplers[texslot]);
+ // TODO: return type
+ ureg_RESINFO(ureg, _dst(), _src(1), resources[_idx(SM4_FILE_RESOURCE, 2)]);
+ break;
+ // TODO: sample index, texture offset
+ case SM4_OPCODE_LD: // dst, coord_int, res; mipmap level in last coord_int arg
+ ureg_LOAD(ureg, _dst(), _src(1), resources[_idx(SM4_FILE_RESOURCE, 2)]);
break;
- };
- // TODO: sample offset, sample index
- case SM4_OPCODE_LD: // dst, coord_int, res; mipmap level in last coord_int arg (ouch)
case SM4_OPCODE_LD_MS:
- {
- unsigned texslot = _texslot(false);
- unsigned dim = 0;
- switch(targets[texslot].first)
- {
- case TGSI_TEXTURE_1D:
- dim = 1;
- break;
- case TGSI_TEXTURE_2D:
- case TGSI_TEXTURE_RECT:
- dim = 2;
- break;
- case TGSI_TEXTURE_3D:
- dim = 3;
- break;
- default:
- check(0);
- }
- struct ureg_dst tmp = _tmp();
- if(avoid_txf)
- {
- struct ureg_src texcoord;
- if(!avoid_int)
- {
- ureg_I2F(ureg, tmp, _src(1));
- texcoord = ureg_src(tmp);
- }
- else
- texcoord = _src(1);
-
- ureg_TXL(ureg, _dst(), tex_target(texslot), ureg_swizzle(texcoord, 0, 1, 2, dim), samplers[texslot]);
- }
- else
- ureg_TXF(ureg, _dst(), tex_target(texslot), ureg_swizzle(_src(1), 0, 1, 2, dim), samplers[texslot]);
+ ureg_LOAD_MS(ureg, _dst(), _src(1), resources[_idx(SM4_FILE_RESOURCE, 2)]);
break;
- }
case SM4_OPCODE_SAMPLE: // dst, coord, res, samp
- {
- unsigned texslot = _texslot();
- ureg_TEX(ureg, _dst(), tex_target(texslot), _src(1), samplers[texslot]);
+ ureg_SAMPLE(ureg, _dst(), _src(1), resources[_idx(SM4_FILE_RESOURCE, 2)], samplers[_idx(SM4_FILE_SAMPLER, 3)]);
break;
- }
case SM4_OPCODE_SAMPLE_B: // dst, coord, res, samp, bias.x
- {
- unsigned texslot = _texslot();
- struct ureg_dst tmp = _tmp();
- ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_XYZ), _src(1));
- ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_W), ureg_swizzle(_src(4), 0, 0, 0, 0));
- ureg_TXB(ureg, _dst(), tex_target(texslot), ureg_src(tmp), samplers[texslot]);
+ ureg_SAMPLE_B(ureg, _dst(), _src(1), resources[_idx(SM4_FILE_RESOURCE, 2)], samplers[_idx(SM4_FILE_SAMPLER, 3)], _src(4));
break;
- }
case SM4_OPCODE_SAMPLE_C: // dst, coord, res, samp, comp.x
- {
- unsigned texslot = _texslot();
- struct ureg_dst tmp = _tmp();
- ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_XY), _src(1));
- ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Z), ureg_swizzle(_src(4), 0, 0, 0, 0));
- ureg_TEX(ureg, _dst(), tex_target(texslot), ureg_src(tmp), samplers[texslot]);
+ ureg_SAMPLE_C(ureg, _dst(), _src(1), resources[_idx(SM4_FILE_RESOURCE, 2)], samplers[_idx(SM4_FILE_SAMPLER, 3)], _src(4));
break;
- }
case SM4_OPCODE_SAMPLE_C_LZ: // dst, coord, res, samp, comp.x
- {
- unsigned texslot = _texslot();
- struct ureg_dst tmp = _tmp();
- ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_XY), _src(1));
- ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Z), ureg_swizzle(_src(4), 0, 0, 0, 0));
- ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_W), ureg_imm1f(ureg, 0.0));
- ureg_TXL(ureg, _dst(), tex_target(texslot), ureg_src(tmp), samplers[texslot]);
+ ureg_SAMPLE_C_LZ(ureg, _dst(), _src(1), resources[_idx(SM4_FILE_RESOURCE, 2)], samplers[_idx(SM4_FILE_SAMPLER, 3)], _src(4));
break;
- }
case SM4_OPCODE_SAMPLE_D: // dst, coord, res, samp, ddx, ddy
- {
- unsigned texslot = _texslot();
- ureg_TXD(ureg, _dst(), tex_target(texslot), _src(1), samplers[texslot], _src(4), _src(5));
+ ureg_SAMPLE_D(ureg, _dst(), _src(1), resources[_idx(SM4_FILE_RESOURCE, 2)], samplers[_idx(SM4_FILE_SAMPLER, 3)], _src(4), _src(5));
break;
- }
case SM4_OPCODE_SAMPLE_L: // dst, coord, res, samp, bias.x
{
- unsigned texslot = _texslot();
struct ureg_dst tmp = _tmp();
ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_XYZ), _src(1));
ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_W), ureg_swizzle(_src(4), 0, 0, 0, 0));
- ureg_TXL(ureg, _dst(), tex_target(texslot), ureg_src(tmp), samplers[texslot]);
+ ureg_SAMPLE_L(ureg, _dst(), ureg_src(tmp), resources[_idx(SM4_FILE_RESOURCE, 2)], samplers[_idx(SM4_FILE_SAMPLER, 3)]);
break;
}
default:
fail("Malformed control flow");
if(!sm4_find_labels(program))
fail("Failed to locate labels");
- if(!sm4_allocate_resource_sampler_pairs(program))
- fail("Unsupported (indirect?) accesses to resources and/or samplers");
ureg = ureg_create(processor);
in_sub = false;
- for(unsigned i = 0; i < program.slot_to_resource.size(); ++i)
- samplers.push_back(ureg_DECL_sampler(ureg, i));
-
sm4_to_tgsi_insn_num.resize(program.insns.size());
for(unsigned insn_num = 0; insn_num < program.dcls.size(); ++insn_num)
{
targets[idx].second = TGSI_TEXTURE_SHADOW2D;
break;
}
+ if(resources.size() <= (unsigned)idx)
+ resources.resize(idx + 1);
+ resources[idx] = ureg_DECL_resource(ureg, idx, targets[idx].first,
+ res_return_type(dcl.rrt.x),
+ res_return_type(dcl.rrt.y),
+ res_return_type(dcl.rrt.z),
+ res_return_type(dcl.rrt.w));
break;
case SM4_OPCODE_DCL_SAMPLER:
check(idx >= 0);
sampler_modes.resize(idx + 1);
check(!dcl.dcl_sampler.mono);
sampler_modes[idx] = dcl.dcl_sampler.shadow;
+ if(samplers.size() <= (unsigned)idx)
+ samplers.resize(idx + 1);
+ samplers[idx] = ureg_DECL_sampler(ureg, idx);
break;
case SM4_OPCODE_DCL_CONSTANT_BUFFER:
check(dcl.op->num_indices == 2);