Adding GetStreamInfo functionality (and passing corresponding unit test).
Review URL: http://codereview.chromium.org/147237 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19859 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
o3d
command_buffer
client
common
service
core
cross
command_buffer
@ -207,5 +207,68 @@ void EffectHelper::DestroyEffectParameters(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EffectHelper::GetEffectStreams(ResourceID effect_id,
|
||||||
|
std::vector<EffectStreamDesc> *descs) {
|
||||||
|
using effect_stream::Desc;
|
||||||
|
DCHECK_NE(effect_id, kInvalidResource);
|
||||||
|
|
||||||
|
// Get the param count.
|
||||||
|
Uint32 *retval = shm_allocator_->AllocTyped<Uint32>(1);
|
||||||
|
CommandBufferEntry args[5];
|
||||||
|
args[0].value_uint32 = effect_id;
|
||||||
|
args[1].value_uint32 = sizeof(*retval);
|
||||||
|
args[2].value_uint32 = shm_id_;
|
||||||
|
args[3].value_uint32 = shm_allocator_->GetOffset(retval);
|
||||||
|
helper_->AddCommand(GET_STREAM_COUNT, 4, args);
|
||||||
|
// Finish has to be called to get the result.
|
||||||
|
helper_->Finish();
|
||||||
|
|
||||||
|
// We could have failed if the effect_id is invalid.
|
||||||
|
if (helper_->interface()->GetParseError() !=
|
||||||
|
BufferSyncInterface::PARSE_NO_ERROR) {
|
||||||
|
shm_allocator_->Free(retval);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unsigned int stream_count = *retval;
|
||||||
|
shm_allocator_->Free(retval);
|
||||||
|
unsigned int max_buffer_size = shm_allocator_->GetLargestFreeOrPendingSize();
|
||||||
|
if (max_buffer_size < sizeof(Desc)) { // NOLINT
|
||||||
|
// Not enough memory to get at least 1 stream desc.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
descs->resize(stream_count);
|
||||||
|
|
||||||
|
// Read stream descriptions in batches. We use as much shared memory as
|
||||||
|
// possible so that we only call Finish as little as possible.
|
||||||
|
unsigned int max_stream_per_batch =
|
||||||
|
std::min(stream_count, max_buffer_size / sizeof(Desc)); // NOLINT
|
||||||
|
Desc *raw_descs = shm_allocator_->AllocTyped<Desc>(max_stream_per_batch);
|
||||||
|
DCHECK(raw_descs);
|
||||||
|
for (unsigned int i = 0; i < stream_count; i += max_stream_per_batch) {
|
||||||
|
unsigned int count = std::min(stream_count - i, max_stream_per_batch);
|
||||||
|
for (unsigned int j = 0 ; j < count; ++j) {
|
||||||
|
EffectStreamDesc *desc = &((*descs)[i + j]);
|
||||||
|
Desc *raw_desc = raw_descs + j;
|
||||||
|
args[0].value_uint32 = effect_id;
|
||||||
|
args[1].value_uint32 = i+j;
|
||||||
|
args[2].value_uint32 = sizeof(*raw_desc);
|
||||||
|
args[3].value_uint32 = shm_id_;
|
||||||
|
args[4].value_uint32 = shm_allocator_->GetOffset(raw_desc);
|
||||||
|
helper_->AddCommand(GET_STREAM_DESC, 5, args);
|
||||||
|
}
|
||||||
|
// Finish to get the results.
|
||||||
|
helper_->Finish();
|
||||||
|
DCHECK_EQ(helper_->interface()->GetParseError(),
|
||||||
|
BufferSyncInterface::PARSE_NO_ERROR);
|
||||||
|
for (unsigned int j = 0 ; j < count; ++j) {
|
||||||
|
EffectStreamDesc *desc = &((*descs)[i + j]);
|
||||||
|
Desc *raw_desc = raw_descs + j;
|
||||||
|
desc->semantic = static_cast<vertex_struct::Semantic>(raw_desc->semantic);
|
||||||
|
desc->semantic_index = raw_desc->semantic_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shm_allocator_->Free(raw_descs);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} // namespace command_buffer
|
} // namespace command_buffer
|
||||||
} // namespace o3d
|
} // namespace o3d
|
||||||
|
@ -59,6 +59,10 @@ class EffectHelper {
|
|||||||
// structure (counting strings) for a
|
// structure (counting strings) for a
|
||||||
// param.
|
// param.
|
||||||
};
|
};
|
||||||
|
struct EffectStreamDesc {
|
||||||
|
vertex_struct::Semantic semantic; // The semantic enum type.
|
||||||
|
unsigned int semantic_index;
|
||||||
|
};
|
||||||
|
|
||||||
EffectHelper(CommandBufferHelper *helper,
|
EffectHelper(CommandBufferHelper *helper,
|
||||||
FencedAllocatorWrapper *shm_allocator,
|
FencedAllocatorWrapper *shm_allocator,
|
||||||
@ -119,6 +123,23 @@ class EffectHelper {
|
|||||||
// descs: the vector of descriptions containing the ResourceIDs of the
|
// descs: the vector of descriptions containing the ResourceIDs of the
|
||||||
// parameters to destroy.
|
// parameters to destroy.
|
||||||
void DestroyEffectParameters(const std::vector<EffectParamDesc> &descs);
|
void DestroyEffectParameters(const std::vector<EffectParamDesc> &descs);
|
||||||
|
|
||||||
|
// Gets all the input stream semantics and semantic indices in an
|
||||||
|
// array. These will be retrieved as many as possible at a time. At least
|
||||||
|
// sizeof(effect_param::Desc) must be available for this function to succeed.
|
||||||
|
// This function will call Finish(), hence will block.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// effect_id: the ResourceID of the effect.
|
||||||
|
// descs: A pointer to a vector containing the returned descriptions.
|
||||||
|
// The pointed vector will be cleared.
|
||||||
|
// Returns:
|
||||||
|
// true if successful. Reasons for failure are:
|
||||||
|
// - invalid effect_id,
|
||||||
|
// - not enough memory in the shm_allocator_.
|
||||||
|
bool GetEffectStreams(ResourceID effect_id,
|
||||||
|
std::vector<EffectStreamDesc> *descs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CommandBufferHelper *helper_;
|
CommandBufferHelper *helper_;
|
||||||
FencedAllocatorWrapper *shm_allocator_;
|
FencedAllocatorWrapper *shm_allocator_;
|
||||||
|
@ -293,6 +293,8 @@ enum CommandId {
|
|||||||
SET_PARAM_DATA, // SetParamData, 4 args
|
SET_PARAM_DATA, // SetParamData, 4 args
|
||||||
SET_PARAM_DATA_IMMEDIATE, // SetParamData, 2 args + data
|
SET_PARAM_DATA_IMMEDIATE, // SetParamData, 2 args + data
|
||||||
GET_PARAM_DESC, // GetParamDesc, 4 args
|
GET_PARAM_DESC, // GetParamDesc, 4 args
|
||||||
|
GET_STREAM_COUNT, // GetStreamCount, 4 args.
|
||||||
|
GET_STREAM_DESC, // GetStreamDesc, 5 args
|
||||||
DESTROY_TEXTURE, // DestroyTexture, 1 arg
|
DESTROY_TEXTURE, // DestroyTexture, 1 arg
|
||||||
CREATE_TEXTURE_2D, // CreateTexture2D, 3 args
|
CREATE_TEXTURE_2D, // CreateTexture2D, 3 args
|
||||||
CREATE_TEXTURE_3D, // CreateTexture3D, 4 args
|
CREATE_TEXTURE_3D, // CreateTexture3D, 4 args
|
||||||
|
@ -481,6 +481,34 @@ class GAPIInterface {
|
|||||||
unsigned int size,
|
unsigned int size,
|
||||||
void *data) = 0;
|
void *data) = 0;
|
||||||
|
|
||||||
|
// Gets the number of input streams for an effect, returning it in a memory
|
||||||
|
// buffer as a Uint32.
|
||||||
|
// Parameters:
|
||||||
|
// id: the resource ID of the effect.
|
||||||
|
// size: the size of the data buffer. Must be at least 4 (the size of the
|
||||||
|
// Uint32).
|
||||||
|
// data: the buffer receiving the data.
|
||||||
|
// Returns:
|
||||||
|
// BufferSyncInterface::PARSE_INVALID_ARGUMENTS if invalid arguments are
|
||||||
|
// passed, BufferSyncInterface::PARSE_NO_ERROR otherwise.
|
||||||
|
virtual ParseError GetStreamCount(ResourceID id,
|
||||||
|
unsigned int size,
|
||||||
|
void *data) = 0;
|
||||||
|
|
||||||
|
// Gets the stream semantics, storing them in the data buffer. The stream
|
||||||
|
// is described by an effect_stream::Desc structure which contains a
|
||||||
|
// semantic type and a semantic index.
|
||||||
|
// Parameters:
|
||||||
|
// id: the resource ID of the effect.
|
||||||
|
// index: which stream semantic to get
|
||||||
|
// size: the size of the data buffer. Must be at least 8 (the size of two
|
||||||
|
// Uint32).
|
||||||
|
// data: the buffer receiving the data.
|
||||||
|
virtual ParseError GetStreamDesc(ResourceID id,
|
||||||
|
unsigned int index,
|
||||||
|
unsigned int size,
|
||||||
|
void *data) = 0;
|
||||||
|
|
||||||
// Creates a 2D texture resource.
|
// Creates a 2D texture resource.
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// id: the resource ID of the texture.
|
// id: the resource ID of the texture.
|
||||||
|
@ -134,6 +134,13 @@ struct Desc {
|
|||||||
};
|
};
|
||||||
} // namespace effect_param
|
} // namespace effect_param
|
||||||
|
|
||||||
|
namespace effect_stream {
|
||||||
|
struct Desc {
|
||||||
|
Uint32 semantic; // the semantic type
|
||||||
|
Uint32 semantic_index;
|
||||||
|
};
|
||||||
|
} // namespace effect_stream
|
||||||
|
|
||||||
namespace texture {
|
namespace texture {
|
||||||
// Texture flags.
|
// Texture flags.
|
||||||
enum Flags {
|
enum Flags {
|
||||||
|
@ -367,6 +367,31 @@ BufferSyncInterface::ParseError GAPIDecoder::DoCommand(
|
|||||||
} else {
|
} else {
|
||||||
return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
|
return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
|
||||||
}
|
}
|
||||||
|
case GET_STREAM_COUNT:
|
||||||
|
if (arg_count == 4) {
|
||||||
|
ResourceID id = args[0].value_uint32;
|
||||||
|
unsigned int size = args[1].value_uint32;
|
||||||
|
void *data = GetAddressAndCheckSize(args[2].value_uint32,
|
||||||
|
args[3].value_uint32,
|
||||||
|
size);
|
||||||
|
if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
|
||||||
|
return gapi_->GetStreamCount(id, size, data);
|
||||||
|
} else {
|
||||||
|
return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
|
||||||
|
}
|
||||||
|
case GET_STREAM_DESC:
|
||||||
|
if (arg_count == 5) {
|
||||||
|
ResourceID id = args[0].value_uint32;
|
||||||
|
unsigned int index = args[1].value_uint32;
|
||||||
|
unsigned int size = args[2].value_uint32;
|
||||||
|
void *data = GetAddressAndCheckSize(args[3].value_uint32,
|
||||||
|
args[4].value_uint32,
|
||||||
|
size);
|
||||||
|
if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
|
||||||
|
return gapi_->GetStreamDesc(id, index, size, data);
|
||||||
|
} else {
|
||||||
|
return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
|
||||||
|
}
|
||||||
case DESTROY_TEXTURE:
|
case DESTROY_TEXTURE:
|
||||||
if (arg_count == 1) {
|
if (arg_count == 1) {
|
||||||
return gapi_->DestroyTexture(args[0].value_uint32);
|
return gapi_->DestroyTexture(args[0].value_uint32);
|
||||||
|
@ -153,6 +153,13 @@ class EffectParam: public Resource {
|
|||||||
DISALLOW_COPY_AND_ASSIGN(EffectParam);
|
DISALLOW_COPY_AND_ASSIGN(EffectParam);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class EffectStream: public Resource {
|
||||||
|
public:
|
||||||
|
explicit EffectStream() {}
|
||||||
|
private:
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(EffectStream);
|
||||||
|
};
|
||||||
|
|
||||||
// Texture class, representing a texture resource.
|
// Texture class, representing a texture resource.
|
||||||
class Texture: public Resource {
|
class Texture: public Resource {
|
||||||
public:
|
public:
|
||||||
|
@ -96,6 +96,59 @@ inline D3DCOLOR RGBAToD3DCOLOR(const RGBA &color) {
|
|||||||
FloatToClampedByte(color.alpha));
|
FloatToClampedByte(color.alpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool VerifyHResult(HRESULT hr, const char* file, int line,
|
||||||
|
const char* call) {
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
DLOG(ERROR) << "DX Error in file " << file
|
||||||
|
<< " line " << line << L": "
|
||||||
|
<< DXGetErrorStringA(hr) << L": " << call;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool D3DSemanticToCBSemantic(
|
||||||
|
D3DDECLUSAGE semantic,
|
||||||
|
unsigned int semantic_index,
|
||||||
|
vertex_struct::Semantic *out_semantic,
|
||||||
|
unsigned int *out_semantic_index) {
|
||||||
|
// TODO: what meaning do we really want to put to our semantics ? How
|
||||||
|
// do they match the semantics that are set in the effect ? What combination
|
||||||
|
// of (semantic, index) are supposed to work ?
|
||||||
|
switch (semantic) {
|
||||||
|
case D3DDECLUSAGE_POSITION:
|
||||||
|
if (semantic_index != 0) return false;
|
||||||
|
*out_semantic = vertex_struct::POSITION;
|
||||||
|
*out_semantic_index = 0;
|
||||||
|
return true;
|
||||||
|
case D3DDECLUSAGE_NORMAL:
|
||||||
|
if (semantic_index != 0) return false;
|
||||||
|
*out_semantic = vertex_struct::NORMAL;
|
||||||
|
*out_semantic_index = 0;
|
||||||
|
return true;
|
||||||
|
case D3DDECLUSAGE_TANGENT:
|
||||||
|
if (semantic_index != 0) return false;
|
||||||
|
*out_semantic = vertex_struct::TEX_COORD;
|
||||||
|
*out_semantic_index = 6;
|
||||||
|
return true;
|
||||||
|
case D3DDECLUSAGE_BINORMAL:
|
||||||
|
if (semantic_index != 0) return false;
|
||||||
|
*out_semantic = vertex_struct::TEX_COORD;
|
||||||
|
*out_semantic_index = 7;
|
||||||
|
return true;
|
||||||
|
case D3DDECLUSAGE_COLOR:
|
||||||
|
if (semantic_index > 1) return false;
|
||||||
|
*out_semantic = vertex_struct::COLOR;
|
||||||
|
*out_semantic_index = semantic_index;
|
||||||
|
return true;
|
||||||
|
case D3DDECLUSAGE_TEXCOORD:
|
||||||
|
*out_semantic = vertex_struct::TEX_COORD;
|
||||||
|
*out_semantic_index = semantic_index;
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace command_buffer
|
} // namespace command_buffer
|
||||||
} // namespace o3d
|
} // namespace o3d
|
||||||
|
|
||||||
|
@ -69,13 +69,16 @@ static void LogFXError(LPD3DXBUFFER error_buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EffectD3D9::EffectD3D9(ID3DXEffect *d3d_effect,
|
EffectD3D9::EffectD3D9(ID3DXEffect *d3d_effect,
|
||||||
ID3DXConstantTable *fs_constant_table)
|
ID3DXConstantTable *fs_constant_table,
|
||||||
|
IDirect3DVertexShader9 *d3d_vertex_shader)
|
||||||
: d3d_effect_(d3d_effect),
|
: d3d_effect_(d3d_effect),
|
||||||
fs_constant_table_(fs_constant_table),
|
fs_constant_table_(fs_constant_table),
|
||||||
|
d3d_vertex_shader_(d3d_vertex_shader),
|
||||||
sync_parameters_(false) {
|
sync_parameters_(false) {
|
||||||
for (unsigned int i = 0; i < kMaxSamplerUnits; ++i) {
|
for (unsigned int i = 0; i < kMaxSamplerUnits; ++i) {
|
||||||
samplers_[i] = kInvalidResource;
|
samplers_[i] = kInvalidResource;
|
||||||
}
|
}
|
||||||
|
SetStreams();
|
||||||
}
|
}
|
||||||
// Releases the D3D effect.
|
// Releases the D3D effect.
|
||||||
EffectD3D9::~EffectD3D9() {
|
EffectD3D9::~EffectD3D9() {
|
||||||
@ -86,6 +89,8 @@ EffectD3D9::~EffectD3D9() {
|
|||||||
d3d_effect_->Release();
|
d3d_effect_->Release();
|
||||||
DCHECK(fs_constant_table_);
|
DCHECK(fs_constant_table_);
|
||||||
fs_constant_table_->Release();
|
fs_constant_table_->Release();
|
||||||
|
DCHECK(d3d_vertex_shader_);
|
||||||
|
d3d_vertex_shader_->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compiles the effect, and checks that the effect conforms to what we expect
|
// Compiles the effect, and checks that the effect conforms to what we expect
|
||||||
@ -152,7 +157,17 @@ EffectD3D9 *EffectD3D9::Create(GAPID3D9 *gapi,
|
|||||||
d3d_effect->Release();
|
d3d_effect->Release();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return new EffectD3D9(d3d_effect, table);
|
IDirect3DVertexShader9 *d3d_vertex_shader = NULL;
|
||||||
|
HR(device->CreateVertexShader(pass_desc.pVertexShaderFunction,
|
||||||
|
&d3d_vertex_shader));
|
||||||
|
if (!d3d_vertex_shader) {
|
||||||
|
d3d_effect->Release();
|
||||||
|
table->Release();
|
||||||
|
DLOG(ERROR) << "Failed to create vertex shader";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EffectD3D9(d3d_effect, table, d3d_vertex_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begins rendering with the effect, setting all the appropriate states.
|
// Begins rendering with the effect, setting all the appropriate states.
|
||||||
@ -177,6 +192,11 @@ unsigned int EffectD3D9::GetParamCount() {
|
|||||||
return effect_desc.Parameters;
|
return effect_desc.Parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gets the number of input streams from the shader.
|
||||||
|
unsigned int EffectD3D9::GetStreamCount() {
|
||||||
|
return streams_.size();
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieves the matching DataType from a D3D parameter description.
|
// Retrieves the matching DataType from a D3D parameter description.
|
||||||
static effect_param::DataType GetDataTypeFromD3D(
|
static effect_param::DataType GetDataTypeFromD3D(
|
||||||
const D3DXPARAMETER_DESC &desc) {
|
const D3DXPARAMETER_DESC &desc) {
|
||||||
@ -282,6 +302,38 @@ bool EffectD3D9::SetSamplers(GAPID3D9 *gapi) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EffectD3D9::SetStreams() {
|
||||||
|
if (!d3d_vertex_shader_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
UINT size;
|
||||||
|
d3d_vertex_shader_->GetFunction(NULL, &size);
|
||||||
|
scoped_array<DWORD> function(new DWORD[size]);
|
||||||
|
d3d_vertex_shader_->GetFunction(function.get(), &size);
|
||||||
|
|
||||||
|
UINT num_semantics;
|
||||||
|
HR(D3DXGetShaderInputSemantics(function.get(),
|
||||||
|
NULL,
|
||||||
|
&num_semantics));
|
||||||
|
scoped_array<D3DXSEMANTIC> semantics(new D3DXSEMANTIC[num_semantics]);
|
||||||
|
HR(D3DXGetShaderInputSemantics(function.get(),
|
||||||
|
semantics.get(),
|
||||||
|
&num_semantics));
|
||||||
|
|
||||||
|
streams_.resize(num_semantics);
|
||||||
|
for (UINT i = 0; i < num_semantics; ++i) {
|
||||||
|
vertex_struct::Semantic semantic;
|
||||||
|
unsigned int semantic_index;
|
||||||
|
if (D3DSemanticToCBSemantic(static_cast<D3DDECLUSAGE>(semantics[i].Usage),
|
||||||
|
static_cast<int>(semantics[i].UsageIndex),
|
||||||
|
&semantic, &semantic_index)) {
|
||||||
|
streams_[i].semantic = semantic;
|
||||||
|
streams_[i].semantic_index = semantic_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void EffectD3D9::LinkParam(EffectParamD3D9 *param) {
|
void EffectD3D9::LinkParam(EffectParamD3D9 *param) {
|
||||||
params_.push_back(param);
|
params_.push_back(param);
|
||||||
}
|
}
|
||||||
@ -290,6 +342,23 @@ void EffectD3D9::UnlinkParam(EffectParamD3D9 *param) {
|
|||||||
std::remove(params_.begin(), params_.end(), param);
|
std::remove(params_.begin(), params_.end(), param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fills the Desc structure, appending name and semantic if any, and if enough
|
||||||
|
// room is available in the buffer.
|
||||||
|
bool EffectD3D9::GetStreamDesc(unsigned int index,
|
||||||
|
unsigned int size,
|
||||||
|
void *data) {
|
||||||
|
using effect_stream::Desc;
|
||||||
|
if (size < sizeof(Desc)) // NOLINT
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Desc stream = streams_[index];
|
||||||
|
Desc *desc = static_cast<Desc *>(data);
|
||||||
|
memset(desc, 0, sizeof(*desc));
|
||||||
|
desc->semantic = stream.semantic;
|
||||||
|
desc->semantic_index = stream.semantic_index;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
EffectParamD3D9::EffectParamD3D9(effect_param::DataType data_type,
|
EffectParamD3D9::EffectParamD3D9(effect_param::DataType data_type,
|
||||||
EffectD3D9 *effect,
|
EffectD3D9 *effect,
|
||||||
D3DXHANDLE handle)
|
D3DXHANDLE handle)
|
||||||
@ -559,6 +628,31 @@ BufferSyncInterface::ParseError GAPID3D9::GetParamDesc(
|
|||||||
BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
|
BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gets the stream count from the effect and store it in the memory buffer.
|
||||||
|
BufferSyncInterface::ParseError GAPID3D9::GetStreamCount(
|
||||||
|
ResourceID id,
|
||||||
|
unsigned int size,
|
||||||
|
void *data) {
|
||||||
|
EffectD3D9 *effect = effects_.Get(id);
|
||||||
|
if (!effect || size < sizeof(Uint32)) // NOLINT
|
||||||
|
return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
|
||||||
|
*static_cast<Uint32 *>(data) = effect->GetStreamCount();
|
||||||
|
return BufferSyncInterface::PARSE_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferSyncInterface::ParseError GAPID3D9::GetStreamDesc(
|
||||||
|
ResourceID id,
|
||||||
|
unsigned int index,
|
||||||
|
unsigned int size,
|
||||||
|
void *data) {
|
||||||
|
EffectD3D9 *effect = effects_.Get(id);
|
||||||
|
if (!effect) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
|
||||||
|
return effect->GetStreamDesc(index, size, data) ?
|
||||||
|
BufferSyncInterface::PARSE_NO_ERROR :
|
||||||
|
BufferSyncInterface::PARSE_INVALID_ARGUMENTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// If the current effect is valid, call End on it, and tag for revalidation.
|
// If the current effect is valid, call End on it, and tag for revalidation.
|
||||||
void GAPID3D9::DirtyEffect() {
|
void GAPID3D9::DirtyEffect() {
|
||||||
if (validate_effect_) return;
|
if (validate_effect_) return;
|
||||||
|
@ -80,7 +80,8 @@ class EffectParamD3D9: public EffectParam {
|
|||||||
class EffectD3D9 : public Effect {
|
class EffectD3D9 : public Effect {
|
||||||
public:
|
public:
|
||||||
EffectD3D9(ID3DXEffect *d3d_effect,
|
EffectD3D9(ID3DXEffect *d3d_effect,
|
||||||
ID3DXConstantTable *fs_constant_table);
|
ID3DXConstantTable *fs_constant_table,
|
||||||
|
IDirect3DVertexShader9 *d3d_vertex_shader);
|
||||||
virtual ~EffectD3D9();
|
virtual ~EffectD3D9();
|
||||||
// Compiles and creates an effect from source code.
|
// Compiles and creates an effect from source code.
|
||||||
static EffectD3D9 *Create(GAPID3D9 *gapi,
|
static EffectD3D9 *Create(GAPID3D9 *gapi,
|
||||||
@ -101,8 +102,13 @@ class EffectD3D9 : public Effect {
|
|||||||
EffectParamD3D9 *CreateParam(unsigned int index);
|
EffectParamD3D9 *CreateParam(unsigned int index);
|
||||||
// Creates an effect parameter of the specified name.
|
// Creates an effect parameter of the specified name.
|
||||||
EffectParamD3D9 *CreateParamByName(const char *name);
|
EffectParamD3D9 *CreateParamByName(const char *name);
|
||||||
|
// Gets the number of stream inputs for the effect.
|
||||||
|
unsigned int GetStreamCount();
|
||||||
|
// Gets the stream data with the specified index.
|
||||||
|
bool GetStreamDesc(unsigned int index, unsigned int size, void *data);
|
||||||
private:
|
private:
|
||||||
typedef std::vector<EffectParamD3D9 *> ParamList;
|
typedef std::vector<EffectParamD3D9 *> ParamList;
|
||||||
|
typedef std::vector<effect_stream::Desc> StreamList;
|
||||||
|
|
||||||
// Links a param into this effect.
|
// Links a param into this effect.
|
||||||
void LinkParam(EffectParamD3D9 *param);
|
void LinkParam(EffectParamD3D9 *param);
|
||||||
@ -110,14 +116,19 @@ class EffectD3D9 : public Effect {
|
|||||||
void UnlinkParam(EffectParamD3D9 *param);
|
void UnlinkParam(EffectParamD3D9 *param);
|
||||||
// Sets sampler states.
|
// Sets sampler states.
|
||||||
bool SetSamplers(GAPID3D9 *gapi);
|
bool SetSamplers(GAPID3D9 *gapi);
|
||||||
|
// Sets streams vector.
|
||||||
|
bool SetStreams();
|
||||||
|
|
||||||
ID3DXEffect *d3d_effect_;
|
ID3DXEffect *d3d_effect_;
|
||||||
|
IDirect3DVertexShader9 *d3d_vertex_shader_;
|
||||||
ID3DXConstantTable *fs_constant_table_;
|
ID3DXConstantTable *fs_constant_table_;
|
||||||
ParamList params_;
|
ParamList params_;
|
||||||
|
StreamList streams_;
|
||||||
bool sync_parameters_;
|
bool sync_parameters_;
|
||||||
ResourceID samplers_[kMaxSamplerUnits];
|
ResourceID samplers_[kMaxSamplerUnits];
|
||||||
|
|
||||||
friend class EffectParamD3D9;
|
friend class EffectParamD3D9;
|
||||||
|
friend class EffectStreamD3D9;
|
||||||
DISALLOW_COPY_AND_ASSIGN(EffectD3D9);
|
DISALLOW_COPY_AND_ASSIGN(EffectD3D9);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -195,6 +195,17 @@ class GAPID3D9 : public GAPIInterface {
|
|||||||
unsigned int size,
|
unsigned int size,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
|
// Implements the GetStreamCount function for D3D9.
|
||||||
|
virtual ParseError GetStreamCount(ResourceID id,
|
||||||
|
unsigned int size,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
// Implements the GetStreamDesc function for D3D9.
|
||||||
|
virtual ParseError GetStreamDesc(ResourceID id,
|
||||||
|
unsigned int index,
|
||||||
|
unsigned int size,
|
||||||
|
void *data);
|
||||||
|
|
||||||
// Implements the CreateTexture2D function for D3D9.
|
// Implements the CreateTexture2D function for D3D9.
|
||||||
virtual ParseError CreateTexture2D(ResourceID id,
|
virtual ParseError CreateTexture2D(ResourceID id,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
|
@ -49,6 +49,7 @@ using command_buffer::CommandBufferEntry;
|
|||||||
using command_buffer::CommandBufferHelper;
|
using command_buffer::CommandBufferHelper;
|
||||||
using command_buffer::ResourceID;
|
using command_buffer::ResourceID;
|
||||||
namespace effect_param = command_buffer::effect_param;
|
namespace effect_param = command_buffer::effect_param;
|
||||||
|
namespace vertex_struct = command_buffer::vertex_struct;
|
||||||
|
|
||||||
EffectCB::EffectCB(ServiceLocator *service_locator, RendererCB *renderer)
|
EffectCB::EffectCB(ServiceLocator *service_locator, RendererCB *renderer)
|
||||||
: Effect(service_locator),
|
: Effect(service_locator),
|
||||||
@ -125,6 +126,11 @@ bool EffectCB::LoadFromFXString(const String& source) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!effect_helper.GetEffectStreams(resource_id, &stream_descs_)) {
|
||||||
|
O3D_ERROR(service_locator()) << "Failed to get streams.";
|
||||||
|
Destroy();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
set_source(source);
|
set_source(source);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -200,8 +206,59 @@ void EffectCB::GetParameterInfo(EffectParameterInfoArray *array) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool CBSemanticToO3DSemantic(
|
||||||
|
vertex_struct::Semantic semantic,
|
||||||
|
unsigned int semantic_index,
|
||||||
|
Stream::Semantic *out_semantic,
|
||||||
|
unsigned int *out_semantic_index) {
|
||||||
|
switch (semantic) {
|
||||||
|
case vertex_struct::POSITION:
|
||||||
|
if (semantic_index != 0) return false;
|
||||||
|
*out_semantic = Stream::POSITION;
|
||||||
|
*out_semantic_index = 0;
|
||||||
|
return true;
|
||||||
|
case vertex_struct::NORMAL:
|
||||||
|
if (semantic_index != 0) return false;
|
||||||
|
*out_semantic = Stream::NORMAL;
|
||||||
|
*out_semantic_index = 0;
|
||||||
|
return true;
|
||||||
|
case vertex_struct::COLOR:
|
||||||
|
if (semantic_index > 1) return false;
|
||||||
|
*out_semantic = Stream::COLOR;
|
||||||
|
*out_semantic_index = semantic_index;
|
||||||
|
return true;
|
||||||
|
case vertex_struct::TEX_COORD:
|
||||||
|
if (semantic_index == 6) {
|
||||||
|
*out_semantic = Stream::TANGENT;
|
||||||
|
*out_semantic_index = 0;
|
||||||
|
return true;
|
||||||
|
} else if (semantic_index == 7) {
|
||||||
|
*out_semantic = Stream::BINORMAL;
|
||||||
|
*out_semantic_index = 0;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
*out_semantic = Stream::TEXCOORD;
|
||||||
|
*out_semantic_index = semantic_index;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
void EffectCB::GetStreamInfo(EffectStreamInfoArray *array) {
|
void EffectCB::GetStreamInfo(EffectStreamInfoArray *array) {
|
||||||
// TODO(rlp)
|
DCHECK(array);
|
||||||
|
array->clear();
|
||||||
|
for (unsigned int i = 0; i < stream_descs_.size(); ++i) {
|
||||||
|
Stream::Semantic semantic;
|
||||||
|
unsigned int semantic_index;
|
||||||
|
if (CBSemanticToO3DSemantic(stream_descs_[i].semantic,
|
||||||
|
stream_descs_[i].semantic_index,
|
||||||
|
&semantic,
|
||||||
|
&semantic_index)) {
|
||||||
|
array->push_back(EffectStreamInfo(semantic, semantic_index));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace o3d
|
} // namespace o3d
|
||||||
|
@ -75,9 +75,9 @@ class EffectCB : public Effect {
|
|||||||
// The command buffer resource ID for the effect.
|
// The command buffer resource ID for the effect.
|
||||||
command_buffer::ResourceID resource_id_;
|
command_buffer::ResourceID resource_id_;
|
||||||
std::vector<EffectHelper::EffectParamDesc> param_descs_;
|
std::vector<EffectHelper::EffectParamDesc> param_descs_;
|
||||||
|
std::vector<EffectHelper::EffectStreamDesc> stream_descs_;
|
||||||
// A generation counter to dirty ParamCacheCBs.
|
// A generation counter to dirty ParamCacheCBs.
|
||||||
unsigned int generation_;
|
unsigned int generation_;
|
||||||
|
|
||||||
// The renderer that created this effect.
|
// The renderer that created this effect.
|
||||||
RendererCB *renderer_;
|
RendererCB *renderer_;
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(EffectCB);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(EffectCB);
|
||||||
|
Reference in New Issue
Block a user