diff options
Diffstat (limited to 'src/gallium/state_trackers/d3d1x/d3d1xshader/src')
7 files changed, 1398 insertions, 0 deletions
diff --git a/src/gallium/state_trackers/d3d1x/d3d1xshader/src/dxbc_dump.cpp b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/dxbc_dump.cpp new file mode 100644 index 00000000000..a3feec74463 --- /dev/null +++ b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/dxbc_dump.cpp @@ -0,0 +1,43 @@ +/************************************************************************** + * + * Copyright 2010 Luca Barbieri + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <memory> +#include <string.h> +#include <iomanip> +#include "dxbc.h" + +std::ostream& operator <<(std::ostream& out, const dxbc_container& container) +{ + for(unsigned i = 0; i < container.chunks.size(); ++i) + { + struct dxbc_chunk_header* chunk = container.chunks[i]; + char fourcc_str[5]; + memcpy(fourcc_str, &chunk->fourcc, 4); + fourcc_str[4] = 0; + out << "# DXBC chunk " << std::setw(2) << i << ": " << fourcc_str << " offset " << ((char*)chunk - (char*)container.data) << " size " << bswap_le32(chunk->size) << "\n"; + } + return out; +} diff --git a/src/gallium/state_trackers/d3d1x/d3d1xshader/src/dxbc_parse.cpp b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/dxbc_parse.cpp new file mode 100644 index 00000000000..6b696ae1afe --- /dev/null +++ b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/dxbc_parse.cpp @@ -0,0 +1,93 @@ +/************************************************************************** + * + * Copyright 2010 Luca Barbieri + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <memory> +#include "dxbc.h" +#include <d3d11shader.h> +#include <d3dcommon.h> + +struct dxbc_container_header +{ + unsigned fourcc; + uint32_t unk[5]; + uint32_t total_size; + uint32_t chunk_count; + uint32_t chunk_offsets[]; +}; + +dxbc_container* dxbc_parse(const void* data, int size) +{ + std::auto_ptr<dxbc_container> container(new dxbc_container()); + container->data = data; + dxbc_container_header* header = (dxbc_container_header*)data; + if(bswap_le32(header->fourcc) != FOURCC_DXBC) + return 0; + unsigned num_chunks = bswap_le32(header->chunk_count); + for(unsigned i = 0; i < num_chunks; ++i) + { + unsigned offset = bswap_le32(header->chunk_offsets[i]); + dxbc_chunk_header* chunk = (dxbc_chunk_header*)((char*)data + offset); + unsigned fourcc = bswap_le32(chunk->fourcc); + container->chunk_map[fourcc] = i; + container->chunks.push_back(chunk); + } + return container.release(); +} + +dxbc_chunk_header* dxbc_find_chunk(const void* data, int size, unsigned fourcc) +{ + dxbc_container_header* header = (dxbc_container_header*)data; + if(bswap_le32(header->fourcc) != FOURCC_DXBC) + return 0; + unsigned num_chunks = bswap_le32(header->chunk_count); + for(unsigned i = 0; i < num_chunks; ++i) + { + unsigned offset = bswap_le32(header->chunk_offsets[i]); + dxbc_chunk_header* chunk = (dxbc_chunk_header*)((char*)data + offset); + if(bswap_le32(chunk->fourcc) == fourcc) + return chunk; + } + return 0; +} + +int dxbc_parse_signature(dxbc_chunk_signature* sig, D3D11_SIGNATURE_PARAMETER_DESC** params) +{ + unsigned count = bswap_le32(sig->count); + *params = (D3D11_SIGNATURE_PARAMETER_DESC*)malloc(sizeof(D3D11_SIGNATURE_PARAMETER_DESC) * count); + + for (unsigned i = 0; i < count; ++i) + { + D3D11_SIGNATURE_PARAMETER_DESC& param = (*params)[i]; + param.SemanticName = (char*)&sig->count + bswap_le32(sig->elements[i].name_offset); + param.SemanticIndex = bswap_le32(sig->elements[i].semantic_index); + param.SystemValueType = (D3D_NAME)bswap_le32(sig->elements[i].system_value_type); + param.ComponentType = (D3D_REGISTER_COMPONENT_TYPE)bswap_le32(sig->elements[i].component_type); + param.Mask = sig->elements[i].mask; + param.ReadWriteMask = sig->elements[i].read_write_mask; + param.Stream = sig->elements[i].stream; + } + return count; +} diff --git a/src/gallium/state_trackers/d3d1x/d3d1xshader/src/tpf_analyze.cpp b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/tpf_analyze.cpp new file mode 100644 index 00000000000..a100ee5c3f5 --- /dev/null +++ b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/tpf_analyze.cpp @@ -0,0 +1,186 @@ +/************************************************************************** + * + * Copyright 2010 Luca Barbieri + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <vector> +#include <set> +#include "tpf.h" + +#define check(x) do {if(!(x)) return false;} while(0) + +bool tpf_link_cf_insns(tpf_program& program) +{ + if(program.cf_insn_linked.size()) + return true; + + program.cf_insn_linked.resize(program.insns.size()); + std::vector<int> cf_insn_linked; + memset(&cf_insn_linked[0], 0xff, cf_insn_linked.size() * sizeof(int)); + std::vector<unsigned> cf_stack; + for(unsigned insn_num = 0; insn_num < program.insns.size(); ++insn_num) + { + unsigned v; + switch(program.insns[insn_num]->opcode) + { + case TPF_OPCODE_LOOP: + cf_stack.push_back(insn_num); + break; + case TPF_OPCODE_ENDLOOP: + check(!cf_stack.empty()); + v = cf_stack.back(); + check(program.insns[v]->opcode == TPF_OPCODE_LOOP); + cf_insn_linked[v] = insn_num; + cf_insn_linked[insn_num] = v; + cf_stack.pop_back(); + break; + case TPF_OPCODE_IF: + case TPF_OPCODE_SWITCH: + cf_insn_linked[insn_num] = insn_num; // later changed + cf_stack.push_back(insn_num); + break; + case TPF_OPCODE_ELSE: + case TPF_OPCODE_CASE: + check(!cf_stack.empty()); + v = cf_stack.back(); + if(program.insns[insn_num]->opcode == TPF_OPCODE_ELSE) + check(program.insns[v]->opcode == TPF_OPCODE_IF); + else + check(program.insns[v]->opcode == TPF_OPCODE_SWITCH || program.insns[v]->opcode == TPF_OPCODE_CASE); + cf_insn_linked[insn_num] = cf_insn_linked[v]; // later changed + cf_insn_linked[v] = insn_num; + cf_stack.back() = insn_num; + break; + case TPF_OPCODE_ENDSWITCH: + case TPF_OPCODE_ENDIF: + check(!cf_stack.empty()); + v = cf_stack.back(); + if(program.insns[insn_num]->opcode == TPF_OPCODE_ENDIF) + check(program.insns[v]->opcode == TPF_OPCODE_IF || program.insns[v]->opcode == TPF_OPCODE_ELSE); + else + check(program.insns[v]->opcode == TPF_OPCODE_SWITCH || program.insns[v]->opcode == TPF_OPCODE_CASE); + cf_insn_linked[insn_num] = cf_insn_linked[v]; + cf_insn_linked[v] = insn_num; + cf_stack.pop_back(); + break; + } + } + check(cf_stack.empty()); + program.cf_insn_linked.swap(cf_insn_linked); + return true; +} + +bool tpf_find_labels(tpf_program& program) +{ + if(program.labels_found) + return true; + + std::vector<int> labels; + for(unsigned insn_num = 0; insn_num < program.insns.size(); ++insn_num) + { + switch(program.insns[insn_num]->opcode) + { + case TPF_OPCODE_LABEL: + if(program.insns[insn_num]->num_ops > 0) + { + tpf_op& op = *program.insns[insn_num]->ops[0]; + if(op.file == TPF_FILE_LABEL && op.has_simple_index()) + { + unsigned idx = (unsigned)op.indices[0].disp; + if(idx >= labels.size()) + labels.resize(idx + 1); + labels[idx] = insn_num; + } + } + break; + } + } + program.label_to_insn_num.swap(labels); + program.labels_found = true; + return true; +} + +bool tpf_allocate_resource_sampler_pairs(tpf_program& program) +{ + if(program.resource_sampler_slots_assigned) + return true; + + std::set<std::pair<int, int> > pairs; + std::set<int> resinfos; + + for(unsigned insn_num = 0; insn_num < program.insns.size(); ++insn_num) + { + int resource = -1; + int sampler = -2; + for(unsigned i = 0; i < program.insns[insn_num]->num_ops; ++i) + { + tpf_op* op = program.insns[insn_num]->ops[i].get(); + if(op) + { + if(op->file == TPF_FILE_RESOURCE) + { + if(!op->has_simple_index() || resource >= 0) + return false; + resource = (int)op->indices[0].disp; + } + if(op->file == TPF_FILE_SAMPLER) + { + if(!op->has_simple_index() || sampler >= 0) + return false; + sampler = (int)op->indices[0].disp; + } + } + } + + unsigned opcode = program.insns[insn_num]->opcode; + if(opcode == TPF_OPCODE_LD || opcode == TPF_OPCODE_LD_MS) + sampler = -1; + if(sampler >= -1 && resource >= 0) + pairs.insert(std::make_pair(resource, sampler)); + if(opcode == TPF_OPCODE_RESINFO) + resinfos.insert(resource); + } + + for(std::set<std::pair<int, int> >::iterator i = pairs.begin(); i != pairs.end(); ++i) + { + program.resource_sampler_to_slot[*i] = program.slot_to_resource.size(); + if(!program.resource_to_slot.count(i->first)) + { + program.resource_to_slot[i->first] = program.slot_to_resource.size(); + resinfos.erase(i->first); + } + program.slot_to_resource.push_back(i->first); + program.slot_to_sampler.push_back(i->second); + } + + for(std::set<int>::iterator i = resinfos.begin(); i != resinfos.end(); ++i) + { + program.resource_sampler_to_slot[std::make_pair(*i, -1)] = program.slot_to_resource.size(); + program.resource_to_slot[*i] = program.slot_to_resource.size(); + program.slot_to_resource.push_back(*i); + program.slot_to_sampler.push_back(-1); + } + program.resource_sampler_slots_assigned = true; + return true; +} diff --git a/src/gallium/state_trackers/d3d1x/d3d1xshader/src/tpf_dump.cpp b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/tpf_dump.cpp new file mode 100644 index 00000000000..2e6e0949a8a --- /dev/null +++ b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/tpf_dump.cpp @@ -0,0 +1,222 @@ +/************************************************************************** + * + * Copyright 2010 Luca Barbieri + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "tpf.h" + +// TODO: we should fix this to output the same syntax as fxc, if tpf_dump_ms_syntax is set + +bool tpf_dump_ms_syntax = true; + +std::ostream& operator <<(std::ostream& out, const tpf_op& op) +{ + if(op.neg) + out << '-'; + if(op.abs) + out << '|'; + if(op.file == TPF_FILE_IMMEDIATE32) + { + out << "l("; + for(unsigned i = 0; i < op.comps; ++i) + { + if(i) + out << ", "; + out << op.imm_values[i].f32; + } + out << ")"; + } + else if(op.file == TPF_FILE_IMMEDIATE64) + { + out << "d("; + for(unsigned i = 0; i < op.comps; ++i) + { + if(i) + out << ", "; + out << op.imm_values[i].f64; + } + out << ")"; + return out; + } + else + { + bool naked = false; + if(tpf_dump_ms_syntax) + { + switch(op.file) + { + case TPF_FILE_TEMP: + case TPF_FILE_INPUT: + case TPF_FILE_OUTPUT: + case TPF_FILE_CONSTANT_BUFFER: + case TPF_FILE_INDEXABLE_TEMP: + case TPF_FILE_UNORDERED_ACCESS_VIEW: + case TPF_FILE_THREAD_GROUP_SHARED_MEMORY: + naked = true; + break; + default: + naked = false; + break; + } + } + + out << (tpf_dump_ms_syntax ? tpf_file_ms_names : tpf_file_names)[op.file]; + + if(op.indices[0].reg.get()) + naked = false; + + for(unsigned i = 0; i < op.num_indices; ++i) + { + if(!naked || i) + out << '['; + if(op.indices[i].reg.get()) + { + out << *op.indices[i].reg; + if(op.indices[i].disp) + out << '+' << op.indices[i].disp; + } + else + out << op.indices[i].disp; + if(!naked || i) + out << ']'; + } + if(op.comps) + { + switch(op.mode) + { + case TPF_OPERAND_MODE_MASK: + out << (tpf_dump_ms_syntax ? '.' : '!'); + for(unsigned i = 0; i < op.comps; ++i) + { + if(op.mask & (1 << i)) + out << "xyzw"[i]; + } + break; + case TPF_OPERAND_MODE_SWIZZLE: + out << '.'; + for(unsigned i = 0; i < op.comps; ++i) + out << "xyzw"[op.swizzle[i]]; + break; + case TPF_OPERAND_MODE_SCALAR: + out << (tpf_dump_ms_syntax ? '.' : ':'); + out << "xyzw"[op.swizzle[0]]; + break; + } + } + } + if(op.abs) + out << '|'; + return out; +} + +std::ostream& operator <<(std::ostream& out, const tpf_dcl& dcl) +{ + out << tpf_opcode_names[dcl.opcode]; + switch(dcl.opcode) + { + case TPF_OPCODE_DCL_GLOBAL_FLAGS: + if(dcl.dcl_global_flags.allow_refactoring) + out << " refactoringAllowed"; + if(dcl.dcl_global_flags.early_depth_stencil) + out << " forceEarlyDepthStencil"; + if(dcl.dcl_global_flags.fp64) + out << " enableDoublePrecisionFloatOps"; + if(dcl.dcl_global_flags.enable_raw_and_structured_in_non_cs) + out << " enableRawAndStructuredBuffers"; + break; + case TPF_OPCODE_DCL_INPUT_PS: + case TPF_OPCODE_DCL_INPUT_PS_SIV: + case TPF_OPCODE_DCL_INPUT_PS_SGV: + out << ' ' << tpf_interpolation_names[dcl.dcl_input_ps.interpolation]; + break; + case TPF_OPCODE_DCL_TEMPS: + out << ' ' << dcl.num; + break; + default: + break; + } + if(dcl.op.get()) + out << ' ' << *dcl.op; + switch(dcl.opcode) + { + case TPF_OPCODE_DCL_CONSTANT_BUFFER: + out << ", " << (dcl.dcl_constant_buffer.dynamic ? "dynamicIndexed" : "immediateIndexed"); + break; + case TPF_OPCODE_DCL_INPUT_SIV: + case TPF_OPCODE_DCL_INPUT_SGV: + case TPF_OPCODE_DCL_OUTPUT_SIV: + case TPF_OPCODE_DCL_OUTPUT_SGV: + case TPF_OPCODE_DCL_INPUT_PS_SIV: + case TPF_OPCODE_DCL_INPUT_PS_SGV: + out << ", " << tpf_sv_names[dcl.num]; + break; + } + + return out; +} + +std::ostream& operator <<(std::ostream& out, const tpf_insn& insn) +{ + out << tpf_opcode_names[insn.opcode]; + if(insn.insn.sat) + out << "_sat"; + for(unsigned i = 0; i < insn.num_ops; ++i) + { + if(i) + out << ','; + out << ' ' << *insn.ops[i]; + } + return out; +} + +std::ostream& operator <<(std::ostream& out, const tpf_program& program) +{ + out << "pvghdc"[program.version.type] << "s_" << program.version.major << "_" << program.version.minor << "\n"; + for(unsigned i = 0; i < program.dcls.size(); ++i) + out << *program.dcls[i] << "\n"; + + for(unsigned i = 0; i < program.insns.size(); ++i) + out << *program.insns[i] << "\n"; + return out; +} + +void tpf_op::dump() +{ + std::cout << *this; +} + +void tpf_insn::dump() +{ + std::cout << *this; +} + +void tpf_dcl::dump() +{ + std::cout << *this; +} + +void tpf_program::dump() +{ + std::cout << *this; +} diff --git a/src/gallium/state_trackers/d3d1x/d3d1xshader/src/tpf_parse.cpp b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/tpf_parse.cpp new file mode 100644 index 00000000000..a4f6cc6b661 --- /dev/null +++ b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/tpf_parse.cpp @@ -0,0 +1,424 @@ +/************************************************************************** + * + * Copyright 2010 Luca Barbieri + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "tpf.h" +#include "utils.h" + +#if 1 +#define check(x) assert(x) +#define fail(x) assert(0 && (x)) +#else +#define check(x) do {if(!(x)) throw(#x);} while(0) +#define fail(x) throw(x) +#endif + +struct tpf_parser +{ + unsigned* tokens; + unsigned* tokens_end; + tpf_program& program; + + tpf_parser(tpf_program& program, void* p_tokens, unsigned size) + : program(program) + { + tokens = (unsigned*)p_tokens; + tokens_end = (unsigned*)((char*)p_tokens + size); + } + + /* TODO: byteswap if machine is big endian */ + uint32_t read32() + { + check(tokens < tokens_end); + return bswap_le32(*tokens++); + } + + template<typename T> + void read_token(T* tok) + { + *(unsigned*)tok = read32(); + } + + uint64_t read64() + { + unsigned a = read32(); + unsigned b = read32(); + return (uint64_t)a | ((uint64_t)b << 32); + } + + void skip(unsigned toskip) + { + tokens += toskip; + } + + void read_op(tpf_op* pop) + { + tpf_op& op = *pop; + tpf_token_operand optok; + read_token(&optok); + assert(optok.file < TPF_FILE_COUNT); + op.swizzle[0] = 0; + op.swizzle[1] = 1; + op.swizzle[2] = 2; + op.swizzle[3] = 3; + op.mask = 0xf; + switch(optok.comps_enum) + { + case TPF_OPERAND_COMPS_0: + op.comps = 0; + break; + case TPF_OPERAND_COMPS_1: + op.comps = 1; + break; + case TPF_OPERAND_COMPS_4: + op.comps = 4; + op.mode = optok.mode; + switch(optok.mode) + { + case TPF_OPERAND_MODE_MASK: + op.mask = TPF_OPERAND_SEL_MASK(optok.sel); + break; + case TPF_OPERAND_MODE_SWIZZLE: + op.swizzle[0] = TPF_OPERAND_SEL_SWZ(optok.sel, 0); + op.swizzle[1] = TPF_OPERAND_SEL_SWZ(optok.sel, 1); + op.swizzle[2] = TPF_OPERAND_SEL_SWZ(optok.sel, 2); + op.swizzle[3] = TPF_OPERAND_SEL_SWZ(optok.sel, 3); + break; + case TPF_OPERAND_MODE_SCALAR: + op.swizzle[0] = op.swizzle[1] = op.swizzle[2] = op.swizzle[3] = TPF_OPERAND_SEL_SCALAR(optok.sel); + break; + } + break; + case TPF_OPERAND_COMPS_N: + fail("Unhandled operand component type"); + } + op.file = (tpf_file)optok.file; + op.num_indices = optok.num_indices; + + if(optok.extended) + { + tpf_token_operand_extended optokext; + read_token(&optokext); + if(optokext.type == 0) + {} + else if(optokext.type == 1) + { + op.neg = optokext.neg; + op.abs= optokext.abs; + } + else + fail("Unhandled extended operand token type"); + } + + for(unsigned i = 0; i < op.num_indices; ++i) + { + unsigned repr; + if(i == 0) + repr = optok.index0_repr; + else if(i == 1) + repr = optok.index1_repr; + else if(i == 2) + repr = optok.index2_repr; + else + fail("Unhandled operand index representation"); + op.indices[0].disp = 0; + // TODO: is disp supposed to be signed here?? + switch(repr) + { + case TPF_OPERAND_INDEX_REPR_IMM32: + op.indices[i].disp = (int32_t)read32(); + break; + case TPF_OPERAND_INDEX_REPR_IMM64: + op.indices[i].disp = read64(); + break; + case TPF_OPERAND_INDEX_REPR_REG: +relative: + op.indices[i].reg.reset(new tpf_op()); + read_op(&*op.indices[0].reg); + break; + case TPF_OPERAND_INDEX_REPR_REG_IMM32: + op.indices[i].disp = (int32_t)read32(); + goto relative; + case TPF_OPERAND_INDEX_REPR_REG_IMM64: + op.indices[i].disp = read64(); + goto relative; + } + } + + if(op.file == TPF_FILE_IMMEDIATE32) + { + for(unsigned i = 0; i < op.comps; ++i) + op.imm_values[i].i32 = read32(); + } + else if(op.file == TPF_FILE_IMMEDIATE64) + { + for(unsigned i = 0; i < op.comps; ++i) + op.imm_values[i].i64 = read64(); + } + } + + void do_parse() + { + read_token(&program.version); + + unsigned lentok = read32(); + tokens_end = tokens - 2 + lentok; + + while(tokens != tokens_end) + { + tpf_token_instruction insntok; + read_token(&insntok); + unsigned* insn_end = tokens - 1 + insntok.length; + tpf_opcode opcode = (tpf_opcode)insntok.opcode; + check(opcode < TPF_OPCODE_D3D11_COUNT); + + if(opcode == TPF_OPCODE_CUSTOMDATA) + { + unsigned customlen = read32() - 2; + skip(customlen); + continue; + } + + if((opcode >= TPF_OPCODE_DCL_RESOURCE && opcode <= TPF_OPCODE_DCL_GLOBAL_FLAGS) + || (opcode >= TPF_OPCODE_DCL_STREAM && opcode <= TPF_OPCODE_DCL_RESOURCE_STRUCTURED)) + { + tpf_dcl& dcl = *new tpf_dcl; + program.dcls.push_back(&dcl); + (tpf_token_instruction&)dcl = insntok; + + tpf_token_instruction_extended exttok; + memcpy(&exttok, &insntok, sizeof(exttok)); + while(exttok.extended) + { + read_token(&exttok); + } + +#define READ_OP_ANY dcl.op.reset(new tpf_op()); read_op(&*dcl.op); +#define READ_OP(FILE) READ_OP_ANY + //check(dcl.op->file == TPF_FILE_##FILE); + + switch(opcode) + { + case TPF_OPCODE_DCL_GLOBAL_FLAGS: + break; + case TPF_OPCODE_DCL_RESOURCE: + READ_OP(RESOURCE); + read_token(&dcl.rrt); + break; + case TPF_OPCODE_DCL_SAMPLER: + READ_OP(SAMPLER); + break; + case TPF_OPCODE_DCL_INPUT: + case TPF_OPCODE_DCL_INPUT_PS: + READ_OP(INPUT); + break; + case TPF_OPCODE_DCL_INPUT_SIV: + case TPF_OPCODE_DCL_INPUT_SGV: + case TPF_OPCODE_DCL_INPUT_PS_SIV: + case TPF_OPCODE_DCL_INPUT_PS_SGV: + READ_OP(INPUT); + dcl.sv = (tpf_sv)(uint16_t)read32(); + break; + case TPF_OPCODE_DCL_OUTPUT: + READ_OP(OUTPUT); + break; + case TPF_OPCODE_DCL_OUTPUT_SIV: + case TPF_OPCODE_DCL_OUTPUT_SGV: + READ_OP(OUTPUT); + dcl.sv = (tpf_sv)(uint16_t)read32(); + break; + case TPF_OPCODE_DCL_INDEX_RANGE: + READ_OP_ANY; + check(dcl.op->file == TPF_FILE_INPUT || dcl.op->file == TPF_FILE_OUTPUT); + dcl.num = read32(); + break; + case TPF_OPCODE_DCL_TEMPS: + dcl.num = read32(); + break; + case TPF_OPCODE_DCL_INDEXABLE_TEMP: + READ_OP(INDEXABLE_TEMP); + dcl.indexable_temp.num = read32(); + dcl.indexable_temp.comps = read32(); + break; + case TPF_OPCODE_DCL_CONSTANT_BUFFER: + READ_OP(CONSTANT_BUFFER); + break; + case TPF_OPCODE_DCL_GS_INPUT_PRIMITIVE: + case TPF_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY: + break; + case TPF_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT: + dcl.num = read32(); + break; + case TPF_OPCODE_DCL_GS_INSTANCE_COUNT: + dcl.num = read32(); + break; + case TPF_OPCODE_DCL_INPUT_CONTROL_POINT_COUNT: + case TPF_OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT: + case TPF_OPCODE_DCL_TESS_DOMAIN: + case TPF_OPCODE_DCL_TESS_PARTITIONING: + case TPF_OPCODE_DCL_TESS_OUTPUT_PRIMITIVE: + break; + case TPF_OPCODE_DCL_HS_MAX_TESSFACTOR: + dcl.f32 = read32(); + break; + case TPF_OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT: + dcl.num = read32(); + break; + case TPF_OPCODE_DCL_FUNCTION_BODY: + dcl.num = read32(); + break; + case TPF_OPCODE_DCL_FUNCTION_TABLE: + dcl.num = read32(); + dcl.data = malloc(dcl.num * sizeof(uint32_t)); + for(unsigned i = 0; i < dcl.num; ++i) + ((uint32_t*)dcl.data)[i] = read32(); + break; + case TPF_OPCODE_DCL_INTERFACE: + dcl.intf.id = read32(); + dcl.intf.expected_function_table_length = read32(); + { + uint32_t v = read32(); + dcl.intf.table_length = v & 0xffff; + dcl.intf.array_length = v >> 16; + } + dcl.data = malloc(dcl.intf.table_length * sizeof(uint32_t)); + for(unsigned i = 0; i < dcl.intf.table_length; ++i) + ((uint32_t*)dcl.data)[i] = read32(); + break; + case TPF_OPCODE_DCL_THREAD_GROUP: + dcl.thread_group_size[0] = read32(); + dcl.thread_group_size[1] = read32(); + dcl.thread_group_size[2] = read32(); + break; + case TPF_OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED: + READ_OP(UNORDERED_ACCESS_VIEW); + read_token(&dcl.rrt); + break; + case TPF_OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW: + READ_OP(UNORDERED_ACCESS_VIEW); + break; + case TPF_OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED: + READ_OP(UNORDERED_ACCESS_VIEW); + dcl.structured.stride = read32(); + break; + case TPF_OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW: + READ_OP(THREAD_GROUP_SHARED_MEMORY); + dcl.num = read32(); + break; + case TPF_OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED: + READ_OP(THREAD_GROUP_SHARED_MEMORY); + dcl.structured.stride = read32(); + dcl.structured.count = read32(); + break; + case TPF_OPCODE_DCL_RESOURCE_RAW: + READ_OP(RESOURCE); + break; + case TPF_OPCODE_DCL_RESOURCE_STRUCTURED: + READ_OP(RESOURCE); + dcl.structured.stride = read32(); + break; + case TPF_OPCODE_DCL_STREAM: + /* TODO: dcl_stream is undocumented: what is it? */ + fail("Unhandled dcl_stream since it's undocumented"); + default: + fail("Unhandled declaration"); + } + + check(tokens == insn_end); + } + else + { + tpf_insn& insn = *new tpf_insn; + program.insns.push_back(&insn); + (tpf_token_instruction&)insn = insntok; + + tpf_token_instruction_extended exttok; + memcpy(&exttok, &insntok, sizeof(exttok)); + while(exttok.extended) + { + read_token(&exttok); + if(exttok.type == TPF_TOKEN_INSTRUCTION_EXTENDED_TYPE_SAMPLE_CONTROLS) + { + insn.sample_offset[0] = exttok.sample_controls.offset_u; + insn.sample_offset[1] = exttok.sample_controls.offset_v; + insn.sample_offset[2] = exttok.sample_controls.offset_w; + } + else if(exttok.type == TPF_TOKEN_INSTRUCTION_EXTENDED_TYPE_RESOURCE_DIM) + insn.resource_target = exttok.resource_target.target; + else if(exttok.type == TPF_TOKEN_INSTRUCTION_EXTENDED_TYPE_RESOURCE_RETURN_TYPE) + { + insn.resource_return_type[0] = exttok.resource_return_type.x; + insn.resource_return_type[1] = exttok.resource_return_type.y; + insn.resource_return_type[2] = exttok.resource_return_type.z; + insn.resource_return_type[3] = exttok.resource_return_type.w; + } + } + + switch(opcode) + { + case TPF_OPCODE_INTERFACE_CALL: + insn.num = read32(); + break; + default: + break; + } + + unsigned op_num = 0; + while(tokens != insn_end) + { + check(tokens < insn_end); + check(op_num < TPF_MAX_OPS); + insn.ops[op_num].reset(new tpf_op); + read_op(&*insn.ops[op_num]); + ++op_num; + } + insn.num_ops = op_num; + } + } + } + + const char* parse() + { + try + { + do_parse(); + return 0; + } + catch(const char* error) + { + return error; + } + } +}; + +tpf_program* tpf_parse(void* tokens, int size) +{ + tpf_program* program = new tpf_program; + tpf_parser parser(*program, tokens, size); + if(!parser.parse()) + return program; + delete program; + return 0; +} diff --git a/src/gallium/state_trackers/d3d1x/d3d1xshader/src/tpf_text.cpp b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/tpf_text.cpp new file mode 100644 index 00000000000..94192c92792 --- /dev/null +++ b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/tpf_text.cpp @@ -0,0 +1,385 @@ +/************************************************************************** + * + * Copyright 2010 Luca Barbieri + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +// generated with sed -re 's/TPF_WHATEVER_//; s/=.*//; s,//.*,,; s/,//; s/\s*//g;'|tr '[A-Z]' '[a-z]'|tr -s '\n'|sed -re 's/(.*)/\t"\1",/g' + +const char* tpf_opcode_names[] = +{ + "add", + "and", + "break", + "breakc", + "call", + "callc", + "case", + "continue", + "continuec", + "cut", + "default", + "deriv_rtx", + "deriv_rty", + "discard", + "div", + "dp2", + "dp3", + "dp4", + "else", + "emit", + "emitthencut", + "endif", + "endloop", + "endswitch", + "eq", + "exp", + "frc", + "ftoi", + "ftou", + "ge", + "iadd", + "if", + "ieq", + "ige", + "ilt", + "imad", + "imax", + "imin", + "imul", + "ine", + "ineg", + "ishl", + "ishr", + "itof", + "label", + "ld", + "ld_ms", + "log", + "loop", + "lt", + "mad", + "min", + "max", + "customdata", + "mov", + "movc", + "mul", + "ne", + "nop", + "not", + "or", + "resinfo", + "ret", + "retc", + "round_ne", + "round_ni", + "round_pi", + "round_z", + "rsq", + "sample", + "sample_c", + "sample_c_lz", + "sample_l", + "sample_d", + "sample_b", + "sqrt", + "switch", + "sincos", + "udiv", + "ult", + "uge", + "umul", + "umad", + "umax", + "umin", + "ushr", + "utof", + "xor", + "dcl_resource", + "dcl_constant_buffer", + "dcl_sampler", + "dcl_index_range", + "dcl_gs_output_primitive_topology", + "dcl_gs_input_primitive", + "dcl_max_output_vertex_count", + "dcl_input", + "dcl_input_sgv", + "dcl_input_siv", + "dcl_input_ps", + "dcl_input_ps_sgv", + "dcl_input_ps_siv", + "dcl_output", + "dcl_output_sgv", + "dcl_output_siv", + "dcl_temps", + "dcl_indexable_temp", + "dcl_global_flags", + "d3d10_count", + "lod", + "gather4", + "sample_pos", + "sample_info", + "d3d10_1_count", + "hs_decls", + "hs_control_point_phase", + "hs_fork_phase", + "hs_join_phase", + "emit_stream", + "cut_stream", + "emitthencut_stream", + "interface_call", + "bufinfo", + "deriv_rtx_coarse", + "deriv_rtx_fine", + "deriv_rty_coarse", + "deriv_rty_fine", + "gather4_c", + "gather4_po", + "gather4_po_c", + "rcp", + "f32tof16", + "f16tof32", + "uaddc", + "usubb", + "countbits", + "firstbit_hi", + "firstbit_lo", + "firstbit_shi", + "ubfe", + "ibfe", + "bfi", + "bfrev", + "swapc", + "dcl_stream", + "dcl_function_body", + "dcl_function_table", + "dcl_interface", + "dcl_input_control_point_count", + "dcl_output_control_point_count", + "dcl_tess_domain", + "dcl_tess_partitioning", + "dcl_tess_output_primitive", + "dcl_hs_max_tessfactor", + "dcl_hs_fork_phase_instance_count", + "dcl_hs_join_phase_instance_count", + "dcl_thread_group", + "dcl_unordered_access_view_typed", + "dcl_unordered_access_view_raw", + "dcl_unordered_access_view_structured", + "dcl_thread_group_shared_memory_raw", + "dcl_thread_group_shared_memory_structured", + "dcl_resource_raw", + "dcl_resource_structured", + "ld_uav_typed", + "store_uav_typed", + "ld_raw", + "store_raw", + "ld_structured", + "store_structured", + "atomic_and", + "atomic_or", + "atomic_xor", + "atomic_cmp_store", + "atomic_iadd", + "atomic_imax", + "atomic_imin", + "atomic_umax", + "atomic_umin", + "imm_atomic_alloc", + "imm_atomic_consume", + "imm_atomic_iadd", + "imm_atomic_and", + "imm_atomic_or", + "imm_atomic_xor", + "imm_atomic_exch", + "imm_atomic_cmp_exch", + "imm_atomic_imax", + "imm_atomic_imin", + "imm_atomic_umax", + "imm_atomic_umin", + "sync", + "dadd", + "dmax", + "dmin", + "dmul", + "deq", + "dge", + "dlt", + "dne", + "dmov", + "dmovc", + "dtof", + "ftod", + "eval_snapped", + "eval_sample_index", + "eval_centroid", + "dcl_gs_instance_count", + "d3d11_count", +}; + +const char* tpf_file_names[] = +{ + "temp", + "input", + "output", + "indexable_temp", + "immediate32", + "immediate64", + "sampler", + "resource", + "constant_buffer", + "immediate_constant_buffer", + "label", + "input_primitiveid", + "output_depth", + "null", + "rasterizer", + "output_coverage_mask", + "stream", + "function_body", + "function_table", + "interface", + "function_input", + "function_output", + "output_control_point_id", + "input_fork_instance_id", + "input_join_instance_id", + "input_control_point", + "output_control_point", + "input_patch_constant", + "input_domain_point", + "this_pointer", + "unordered_access_view", + "thread_group_shared_memory", + "input_thread_id", + "input_thread_group_id", + "input_thread_id_in_group", + "input_coverage_mask", + "input_thread_id_in_group_flattened", + "input_gs_instance_id", + "output_depth_greater_equal", + "output_depth_less_equal", + "cycle_counter", +}; + +const char* tpf_file_ms_names[] = +{ + "r", + "v", + "o", + "x", + "l", + "d", + "sampler", + "resource", + "cb", + "icb", + "label", + "vPrim", + "oDepth", + "null", + "rasterizer", + "oMask", + "stream", + "function_body", + "function_table", + "interface", + "function_input", + "function_output", + "vOutputControlPointID", + "vForkInstanceID", + "vJoinInstanceID", + "vicp", + "vocp", + "input_patch_constant", + "vDomain", + "this", + "u", + "g", + "vThreadID", + "vThreadGrouID", + "vThreadIDInGroup", + "vCoverage", + "vThreadIDInGroupFlattened", + "vGSInstanceID", + "oDepthGE", + "oDepthLE", + "vCycleCounter", +}; + +const char* tpf_target_names[] = +{ + "unknown", + "buffer", + "texture1d", + "texture2d", + "texture2dms", + "texture3d", + "texturecube", + "texture1darray", + "texture2darray", + "texture2dmsarray", + "texturecubearray", + "raw_buffer", + "structured_buffer", +}; + +const char* tpf_interpolation_names[] = +{ + "undefined", + "constant", + "linear", + "linear centroid", + "linear noperspective", + "linear noperspective centroid", + "linear sample", + "linear noperspective sample", +}; + +const char* tpf_sv_names[] = +{ + "undefined", + "position", + "clip_distance", + "cull_distance", + "render_target_array_index", + "viewport_array_index", + "vertex_id", + "primitive_id", + "instance_id", + "is_front_face", + "sample_index", + "final_quad_u_eq_0_edge_tessfactor", + "final_quad_v_eq_0_edge_tessfactor", + "final_quad_u_eq_1_edge_tessfactor", + "final_quad_v_eq_1_edge_tessfactor", + "final_quad_u_inside_tessfactor", + "final_quad_v_inside_tessfactor", + "final_tri_u_eq_0_edge_tessfactor", + "final_tri_v_eq_0_edge_tessfactor", + "final_tri_w_eq_0_edge_tessfactor", + "final_tri_inside_tessfactor", + "final_line_detail_tessfactor", + "final_line_density_tessfactor", +}; diff --git a/src/gallium/state_trackers/d3d1x/d3d1xshader/src/utils.h b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/utils.h new file mode 100644 index 00000000000..6e77b51175d --- /dev/null +++ b/src/gallium/state_trackers/d3d1x/d3d1xshader/src/utils.h @@ -0,0 +1,45 @@ +/************************************************************************** + * + * Copyright 2010 Luca Barbieri + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef BYTESWAP_H_ +#define BYTESWAP_H_ + +#include <stdint.h> +#include <assert.h> + +#ifdef WORDS_BIGENDIAN +static inline uint32_t le32_to_cpu(uint32_t v) +{ + return ((v & 0xff) << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | ((v & 0xff000000) >> 24); +} +#else +static inline uint32_t le32_to_cpu(uint32_t v) +{ + return v; +} +#endif + +#endif /* BYTESWAP_H_ */ |